Skip to content
HTML/CSS to ImageDocs

Use the official HCTI Pulumi provider to manage rendering resources from your application’s infrastructure project.

Add the SDK to an existing Pulumi project:

Language Install
TypeScript / JavaScript npm install @html-css-to-image/pulumi
Python pip install pulumi-html-css-to-image
Go go get github.com/htmlcsstoimage/pulumi-html-css-to-image/sdk/go
C# dotnet add package HtmlCssToImage.Pulumi

For Java, use Maven coordinates com.htmlcsstoimage:pulumi. See the provider README for the dependency declaration and YAML examples for programs that do not need a language SDK. Published SDKs automatically locate the matching provider plugin.

Configure a management key for your stack:

Terminal window
pulumi config set html-css-to-image:apiId YOUR_API_ID
pulumi config set --secret html-css-to-image:apiKey

The second command prompts for the key. Alternatively, set HCTI_API_ID and HCTI_API_KEY in the environment running Pulumi. See credentials and state for permissions and state storage.

The examples below use TypeScript in index.ts:

import * as pulumi from "@pulumi/pulumi";
import * as hcti from "@html-css-to-image/pulumi";
const hello = new hcti.ImageHtmlCss("hello", {
html: "<h1>Hello from Pulumi</h1>",
css: "h1 { font-family: Inter; padding: 48px; }",
googleFonts: ["Inter"],
}, { retainOnDelete: true });
export const imageUrl = hello.imageUrl;

Run pulumi preview and pulumi up, then open the returned URL to render the image. Keep your language’s dependency lockfile in version control to make deployments reproducible.

To render during deployment, add an HTTP request that depends on the image URL. Purrl is a community provider for HTTP calls. Choose a request tool that supports the returned method and response format; an image response is binary, not JSON.

For a public image URL, the Pulumi Command provider can run curl and discard the binary response. Install @pulumi/command and ensure curl is available on the machine running Pulumi:

import * as command from "@pulumi/command";
const renderHello = new command.local.Command("render-hello", {
create: 'curl --fail --silent --show-error --location --max-time 120 --output /dev/null "$IMAGE_URL"',
environment: { IMAGE_URL: hello.imageUrl },
triggers: [hello.id],
});

The URL output establishes the dependency. The command runs when created and again when a new image ID replaces it. This explicitly renders the image and can consume rendering credits. No delete command is configured.

For custom-storage-only images, follow renderMethod and renderRequiresAuth: use authenticated PUT to the returned /store URL with credentials that include images:store. Pass credentials through secret inputs; do not substitute a public GET or HEAD request. A failed render fails the deployment step.

For images whose URLs you publish outside the stack, we recommend Pulumi’s retainOnDelete resource option. The setup example enables it. Use it on ImageHtmlCss, ImageUrl, or ImageTemplated to keep the previous image when inputs cause a replacement, and to keep the current image when removing the resource or destroying the stack.

Pulumi stops tracking retained images, so later stack operations will not clean them up. This prevents deletion by Pulumi; it does not change HCTI’s storage or retention policies. Choose your own cleanup process for images you no longer need. protect: true serves a different purpose: it blocks deletion rather than letting replacement proceed while retaining the old image.

Use ImageHtmlCss, as in the setup example, for HTML/CSS designs. Optional fields include viewport dimensions, Google Fonts, PDF options, proxyId, and storageDestinationId.

Unspecified nullable rendering fields are sent as null so the API controls their defaults. Refresh reads metadata without rendering; changing rendering inputs replaces the image. Resource reference.

const homepage = new hcti.ImageUrl("homepage", {
url: "https://example.com",
fullScreen: true,
});

Capture a webpage, optionally adding CSS, request headers, or a proxy. Headers are treated as sensitive resource attributes. Resource reference.

const card = new hcti.Template("card", {
name: "Application card",
html: "<h1>{{title}}</h1>",
css: "h1 { padding: 48px; color: #334155; }",
});

Edits create a new version under the same template ID. This resource manages HTML/CSS templates, not visual block templates. Template guide · Resource reference.

const welcome = new hcti.ImageTemplated("welcome", {
templateId: card.id,
templateVersion: card.version,
templateValues: JSON.stringify({ title: "Welcome" }),
});

Referencing card.version replaces the image when the template changes. Omit templateVersion to select the latest version at image creation; later template changes do not replace that existing image. Version identifiers are strings, preserving the full precision of API version numbers.

templateValues is a sensitive JSON object string. For values containing Pulumi outputs, use pulumi.jsonStringify so dependencies and secret markings are preserved. Resource reference.

const application = new hcti.ApiKey("application", {
name: "Application rendering",
permissions: ["images:create", "templates:read"],
});

Use the apiId and secret apiKey outputs to configure your application or a secrets manager resource. Pulumi tracks the dependency when you pass these outputs to another resource. Updates preserve the secret; destroy disables the key. Import cannot recover the original secret.

Set allFuturePermissions: true only when you intend to grant every current and future permission. In C#, the secret property is ApiKey.Value to avoid a type/member name collision. Management API · Resource reference.

const config = new pulumi.Config();
const renderingProxy = new hcti.Proxy("rendering", {
name: "Rendering proxy",
url: "https://proxy.example.com",
port: 8080,
authentication: {
username: "rendering",
password: config.requireSecret("proxyPassword"),
},
});

Set the password with pulumi config set --secret proxyPassword. Omit authentication for a proxy without credentials. The resource registers an existing proxy; it does not provision a proxy server. Reference renderingProxy.id as proxyId on an image or template. Management API · Resource reference.

const storageConfig = new pulumi.Config();
const images = new hcti.StorageDestination("images", {
name: "Application images",
connectionInfo: {
awsS3: {
bucket: "my-rendered-images",
region: "us-east-1",
roleArn: storageConfig.require("storageRoleArn"),
keyPrefix: "cards",
},
},
});

This example uses an existing bucket and role. You can instead create them with Pulumi’s AWS provider, then pass their outputs to the HCTI destination. Use getAwsStorageExternalId to obtain the external ID and HCTI writer role ARN for the trust policy. Separately managed IAM policies must be attached before destination creation; use Pulumi’s dependsOn option when an output reference alone does not establish that dependency.

Set exactly one object in connectionInfo: awsS3, cloudflareR2, backblazeB2, digitaloceanSpaces, wasabi, googleCloudStorage, or otherS3Compatible. Use secret configuration for access-key secrets. Reference images.id as storageDestinationId on an image or template.

Setting hctiStorageDisabled: true enables custom-storage-only output, which requires an authenticated rendering request. See image lifecycle. Deleting the destination does not delete the bucket or stored files.

Management API · Resource reference · AWS example.

const website = new hcti.OgConfig("website", {
name: "Website cards",
configType: "html_css",
baseUrl: "https://example.com",
defaultOptions: {
selector: "#social-card",
viewportWidth: 1200,
viewportHeight: 630,
},
});

Use html_css to capture your pages or templated to fill a template from page metadata. The resource manages the configuration, not every image served through it. For templated OG configurations, omitting templateVersion follows the latest template when an image is served. Management API · Resource reference.

The provider includes three lookup functions, plus output-aware variants for use with resource outputs:

  • getTemplate: read an existing template’s latest or specified version without managing its lifecycle.
  • getTemplateVersions: list version history, newest first, following pagination up to limit (default 1000).
  • getAwsStorageExternalId: retrieve the external ID and HCTI writer role ARN needed for an AWS trust policy.

Provider examples · Source and issues · IaC overview

Need help?

Talk to a human. Email support@htmlcsstoimage.com and we’ll help you get started.