Component deploy targets
Update trusted raw HTML on sections and rows from GitHub Actions or another deploy pipeline using stable keys.
What deploy targets solve
Component deploy targets give sections and rows a stable deployment key, such as homepage-hero-form, so external build systems can update raw_html without knowing database ids.
Use this when your team builds an interactive component outside StaticPagesApi, compiles it, and wants to push the final mount HTML into one placement or an atomic group of placements.
- Database ids are fine for admin screens and internal API work, but they are brittle in CI/CD scripts.
- Deployment keys are organization-scoped, human-readable, and intended to survive rebuilds, imports, and team handoffs.
- The endpoint updates raw_html only. It does not create pages, sections, rows, templates, categories, tags, or webhooks.
Best fit
Deploy targets are best for trusted organization-authored HTML that is generated by your own build process.
- React, Vue, Svelte, or vanilla JavaScript widgets compiled into static assets.
- Lead forms, calculators, booking widgets, product demos, search modules, or account-adjacent tools.
- Overlay sections where native copy stays editable in StaticPagesApi and the opposite region uses either a directly deployed section fragment or an ordered stack mixing built-in, Liquid-template, and raw_html rows.
- Section-level raw_html when the whole section is intentionally owned by compiled markup.
Create a deployment key
Open the section or row edit screen and set the Deployment key field. After saving, the screen shows a copyable API example for that target.
- Keys must use lowercase letters, numbers, hyphens, and underscores only.
- Use descriptive names such as homepage-hero-form, pricing-calculator, or signup_widget_main.
- A key may be reused by multiple sections and rows in the organization. One PATCH updates every matching target atomically.
- Each section or row can have only one deployment key.
- Every section or row counts separately against the deploy-target quota, even when keys are shared.
- Use {{ deployment_instance_id }} in repeated component mount IDs and JavaScript lookups. It renders as a stable value such as section-42 or row-84.
- Clearing the field removes the deploy target without deleting the section or row.
API endpoint
Send a PATCH request to the key-based endpoint with an organization API token. The token decides which organization can see the key.
curl -X PATCH "https://staticpageapi.com/api/v1/component_deploy_targets/homepage-hero-form" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"raw_html": "<div id=\"lead-form-widget-{{ deployment_instance_id }}\"></div><script>initializeLeadForm(document.getElementById('lead-form-widget-{{ deployment_instance_id }}'))</script>"
}'
Payload
The deployment endpoint accepts one field: raw_html. Blank raw_html is rejected so a bad build cannot accidentally empty a target. The optional {{ deployment_instance_id }} token remains in stored source and is replaced only when each section or row renders.
{
"raw_html": "<div id=\"lead-form-widget-{{ deployment_instance_id }}\"></div>"
}
Response
A successful response lists every target updated by the key and returns a SHA256 digest of the saved HTML. Store or print the digest in CI logs when you want a simple audit trail.
{
"key": "homepage-hero-form",
"target_count": 2,
"targets": [
{
"target_type": "Row",
"target_id": 42,
"instance_id": "row-42",
"updated_at": "2026-06-20T20:15:30Z"
},
{
"target_type": "Section",
"target_id": 84,
"instance_id": "section-84",
"updated_at": "2026-06-20T20:15:30Z"
}
],
"raw_html_sha256": "7ef3d6b6d0a9..."
}
GitHub Actions example
Compile the component, read the built HTML snippet, wrap it as JSON, and PATCH the deploy target. Keep the StaticPagesApi URL and token in repository or organization secrets.
- name: Deploy compiled widget to StaticPagesApi
env:
STATIC_PAGES_API_URL: ${{ secrets.STATIC_PAGES_API_URL }}
STATIC_PAGES_API_TOKEN: ${{ secrets.STATIC_PAGES_API_TOKEN }}
run: |
npm ci
npm run build
HTML=$(cat dist/widget.html)
jq -n --arg raw_html "$HTML" '{raw_html: $raw_html}' > payload.json
curl -X PATCH "$STATIC_PAGES_API_URL/api/v1/component_deploy_targets/homepage-hero-form" \
-H "Authorization: Bearer $STATIC_PAGES_API_TOKEN" \
-H "Content-Type: application/json" \
--data @payload.json
React component repo pattern
A React component repository can export many independent overlay fragments. Keep each deployable component in its own directory with a manifest that names its output file and StaticPagesApi deployment key.
The example static_pages_api_react_component_deploy repository uses React server rendering to build small HTML fragments, then deploys each fragment to the matching component deploy target.
- Use one directory per deployable component, such as components/newsletter-signup.
- Keep component markup focused on the right-side overlay or raw HTML mount point.
- Let StaticPagesApi section and row configuration own the surrounding layout, editable copy, and most styling.
- Use a small behavior script only when the fragment needs browser-side interactivity.
- Use a unique deployment key for placements that release independently. Reuse a key only when every matching placement should receive the same artifact.
Component directory layout
Each component directory should include a React component and a manifest. The shared build script reads every manifest and writes one dist file per component.
static_pages_api_react_component_deploy/
components/
newsletter-signup/
component.jsx
manifest.mjs
lead-capture/
component.jsx
manifest.mjs
dist/
newsletter-signup.html
lead-capture.html
scripts/
build.mjs
deploy.mjs
Component manifest
The manifest connects the local component to a StaticPagesApi deploy target. The deployTargetKey must match the Deployment key saved on the target section or row.
export default {
name: "newsletter-signup",
output: "newsletter-signup.html",
deployTargetKey: "newsletter-signup-page-16"
};
Build and deploy one component
Use the component name to build or deploy one fragment without touching the others. This is the normal workflow when different overlays belong to different pages or release schedules.
npm run build -- newsletter-signup
STATIC_PAGES_API_URL="https://staticpageapi.com" \
STATIC_PAGES_API_TOKEN="YOUR_API_TOKEN" \
npm run deploy -- newsletter-signup
Build and deploy all components
When a release should update every overlay fragment in the repository, run the shared commands without a component name. Each manifest deploys to its own key.
npm run build
STATIC_PAGES_API_URL="https://staticpageapi.com" \
STATIC_PAGES_API_TOKEN="YOUR_API_TOKEN" \
npm run deploy
Recommended component artifact
Keep the raw_html snippet small and stable. It should usually mount public assets rather than inline an entire application bundle. Repeated placements must initialize against their own tokenized mount element.
- Use one tokenized wrapper element, such as <div id="lead-form-widget-{{ deployment_instance_id }}" data-page="home"></div>.
- Load CSS and JavaScript from a CDN, S3, a Rails asset host, Shopify theme assets, WordPress plugin assets, or another public asset URL.
- Use versioned asset filenames when you need rollback behavior.
- Scope CSS to the component wrapper so it does not leak into the host page.
- Do not include secrets, private API keys, or user-specific data in raw_html.
<div id="pricing-calculator-widget-{{ deployment_instance_id }}" data-source="static-pages-api"></div>
<link rel="stylesheet" href="https://cdn.example.com/widgets/pricing-calculator.v3.css">
<script src="https://cdn.example.com/widgets/pricing-calculator.v3.js"></script>
<script>
initializePricingCalculator(
document.getElementById("pricing-calculator-widget-{{ deployment_instance_id }}")
)
</script>
Publishing after deployment
After a deploy target updates raw_html, StaticPagesApi triggers the existing webhook publishing flow for affected pages.
- A row target publishes every page using the row's section.
- A section target publishes every page affected by that section.
- When several matching targets affect the same page, that page is queued once per deployment.
- Webhook delivery history will show the result of each send.
- If no webhooks are attached to the affected page, the raw_html update still saves, but nothing external receives it automatically.
Security and permissions
Deploy targets use the same organization API token model as the rest of the API. Treat tokens like production deploy credentials.
- Use Authorization: Bearer YOUR_API_TOKEN.
- Create a separate API token for each deploy system or repository.
- Rotate or revoke a token if a repository, CI provider, or developer machine is compromised.
- A token can only update deploy targets in its own organization.
- Raw HTML is trusted content. Review what your build pipeline emits before giving it deploy credentials.
Troubleshooting
Most deploy failures map to a small set of response codes.
- 401 Unauthorized: the token is missing, invalid, revoked, or not sent as a bearer token.
- 402 Payment Required: the organization is outside trial or subscription limits for write actions.
- A shared-key deployment returns 402 without changing any target when even one matching target is plan-disabled.
- 404 Not Found: the key does not exist in the token's organization.
- 422 Unprocessable Entity: raw_html is blank or any matching target fails validation; the full deployment is rolled back.
- The page did not update externally: confirm the affected page has an attached webhook and inspect webhook history.
- The widget appears unstyled or broken: confirm public asset URLs, CORS, body-only export head assets, and the destination platform's script restrictions.
© 2026 StaticPagesApi. All rights reserved.
Documentation, examples, prompts, templates, and API guidance are provided for authorized use with StaticPagesApi.