Theme packages (beta)
Beta: package JSON structure, theme tokens and CSS variables, customCss, catalog, and install modes.
Beta. First-party Sites theme packages are in beta. Package ids, install modes, and response shapes may change before general availability.
Theme packages are data-only installable units for Sites websites on styrar.site. A package is JSON: theme tokens, optional sample pages and sections, and optional chrome blocks. Styrar renders that data to HTML on the public host. Install always copies into a draft SiteVersion. The public site never live-links remote theme code.
Plan requirement: API access requires Team or Agency. See pricing.
Base URL: https://api.styrar.com/v1
How authoring works
| You author | Styrar does |
|---|---|
Theme token JSON (colorScheme, fonts, buttons, …) | Maps tokens to CSS variables on the published page |
Optional customCss string | Injects sanitized CSS that can use those variables and published class names |
Optional layout JSON (pages, pageMeta.sections, chrome blocks) | Renders sections and blocks to HTML (same engine as the Sites editor) |
Not supported in a package (and not planned for v0):
- Uploading a zip of HTML / Liquid / React files
- Custom JavaScript (no theme
script.js, no arbitrary client JS in packages) - Live-linked remote themes or third-party marketplace upload
If you need motion or behavior beyond CSS, use Sites interactions and block config in the editor (or via version PATCH), not package JS.
Package structure
First-party packages follow this shape (v0):
{
"schemaVersion": 1,
"id": "styrar.studio",
"name": "Studio",
"description": "Light editorial look with image+text and a CTA banner.",
"author": "Styrar",
"version": "1.0.0",
"category": "portfolio",
"swatch": { "background": "#f7f5f0", "accent": "#1a1a1a" },
"theme": {
"colorScheme": {
"background": "#f7f5f0",
"text": "#1a1a1a",
"accent": "#1a1a1a",
"buttonBg": "#1a1a1a",
"buttonText": "#f7f5f0"
},
"fontFamily": "'Playfair Display', Georgia, serif",
"backgroundType": "color",
"backgroundValue": "#f7f5f0",
"buttonStyle": "outline",
"buttonRadius": "none",
"avatarShape": "square",
"containerWidth": "wide",
"customCss": ""
},
"pages": ["/"],
"pageMeta": {
"/": {
"title": "Home",
"description": "Studio portfolio",
"sections": [
{
"title": "Story",
"layoutMode": "flow",
"styles": null,
"blocks": [
{
"kind": "text",
"config": { "content": "Hello", "align": "left" },
"styles": null
}
]
}
]
}
},
"blocks": [
{
"pagePath": "/",
"sortOrder": 0,
"kind": "hero",
"config": {
"headline": "Craft with clarity",
"subtext": "A calm studio presence.",
"ctaLabel": "View work",
"ctaUrl": "#"
},
"styles": null
}
],
"components": []
}
| Field | Role |
|---|---|
theme | Look tokens. Same shape as SiteVersion.theme. Prefer setting colors/fonts/buttons; omit spacing / customCss if you want token-only install to leave those alone. |
pages | Path list (for example ["/"] or ["/", "/about"]). |
pageMeta | Per-path SEO fields plus sections[] (flow/grid/canvas sections and nested blocks). |
blocks | Page chrome: site_nav, hero, footer, and similar top-level kinds. |
components | Reserved; empty in v0. |
swatch | Gallery preview colors only. |
Fetch a real package with GET /v1/sites/theme-packages/:packageId to inspect a full example.
Theme tokens → CSS variables
Published Sites (and bio) pages set CSS custom properties from theme. Use these in theme.customCss:
| Token field | CSS variable |
|---|---|
colorScheme.background | --bio-bg |
colorScheme.text | --bio-text |
colorScheme.accent | --bio-accent |
colorScheme.buttonBg | --bio-btn-bg |
colorScheme.buttonText | --bio-btn-text |
fontFamily / Google font | --bio-font |
buttonRadius | --bio-btn-radius |
containerWidth | --bio-page-width |
avatarShape | --bio-avatar-radius |
pagePaddingY | --bio-page-padding-y |
pagePaddingX | --bio-page-padding-x |
blockGap | --bio-block-gap |
Other useful fields on theme:
| Field | Values / notes |
|---|---|
backgroundType | color, gradient, animated-gradient, pattern, image, video |
backgroundValue | Color, CSS gradient, pattern id, or media URL |
buttonStyle | filled, outline, ghost |
buttonRadius | pill, lg, md, sm, none |
containerWidth | narrow (480px), medium (640px), wide (800px) |
customCss | Extra CSS string (sanitized at render) |
Styling with CSS (not raw HTML)
You do not ship HTML files. Layout comes from blocks and sections in the package (or the live editor). Visual polish beyond tokens goes in theme.customCss, targeting the classes Styrar emits.
Example:
.bio-link-btn {
letter-spacing: 0.02em;
box-shadow: 0 8px 24px color-mix(in srgb, var(--bio-accent) 25%, transparent);
}
.bio-hero-headline {
font-weight: 600;
}
.bio-site-nav a[data-active="true"] {
color: var(--bio-accent);
}
.bio-footer {
border-top: 1px solid color-mix(in srgb, var(--bio-text) 12%, transparent);
}
Common selectors:
| Selector | Use |
|---|---|
.bio-page | Main content container |
.bio-block | Each content block wrapper |
.bio-section / .bio-section-blocks | Section chrome and nested blocks |
.bio-hero, .bio-hero-headline, .bio-hero-cta | Hero |
.bio-site-nav, .bio-site-nav a[data-active="true"] | Site nav |
.bio-footer | Footer |
.bio-link-btn | Buttons and CTAs |
.bio-text, .bio-heading | Text / heading blocks |
.bio-group | Horizontal / column groups |
In the dashboard Theme editor, Open reference lists the full selector and variable set used on published pages.
Building a layout (blocks, not HTML templates)
Sample layout in a package is structured JSON:
- Chrome
blockson each path: for examplesite_nav,hero,footer. pageMeta[path].sections: each section hastitle,layoutMode(flow|grid|canvas), andblocks[].- Each nested block has
kind(text,image,group,link_button, …),config, and optionalstyles.
Reuse first-party section presets from GET /v1/sites/section-catalog when composing packages (the built-in catalog does this for Studio, Midnight, Soft, and Contrast).
IDs inside sections are optional in the package snapshot. On create or install-theme-package with mode: "full", Styrar materializes fresh section and block ids.
Catalog
| Id | Name | Category |
|---|---|---|
styrar.studio | Studio | portfolio |
styrar.midnight | Midnight | commerce |
styrar.soft | Soft | portfolio |
styrar.contrast | Contrast | agency |
Authorization: Bearer sty_live_your_api_keyAuthorization: Bearer sty_live_your_api_keyList responses are gallery metadata. Get-by-id returns the full package for preview.
Create a site from a package
Pass a package id as templateId (or use a structural starter: blank, portfolio, booking, store).
Authorization: Bearer sty_live_your_api_key
Content-Type: application/json
{
"companyId": "clxyz_company",
"title": "Studio site",
"templateId": "styrar.studio"
}Install onto a draft
Authorization: Bearer sty_live_your_api_key
Content-Type: application/json
{
"packageId": "styrar.midnight",
"mode": "theme"
}mode | Effect |
|---|---|
theme | Merge package colors, fonts, and buttons into the draft. Keeps existing pages and sections. |
full | Replace theme, pages, sections, and chrome with the package sample layout. |
Publish with POST /v1/sites/:id/versions/:versionId/publish when the draft should go live.
Workspace theme presets
Save reusable token snapshots for Sites (not full packages):
| Method | Path | Scope |
|---|---|---|
| GET/POST | /v1/sites/theme-presets | links:read / links:write |
| DELETE | /v1/sites/theme-presets/:id | links:write |
Pass companyId as a query param for company scope.
Related
- Sites overview - create sites and related routes (beta)
- Sites API - full Sites route table
- Authentication - scopes and API keys