Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions content/docs/storefront/themes/cdn-and-caching.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Storefront leverages CDNs and many caching strategies to ensure fast performant
<Callout type="info" title="Use Network Domain while Building Themes">
Always use the store network domain `{store}.29next.store` when developing themes to bypass full page caching and preview your latest updates.
</Callout>

The network domain bypasses the full-page cache. It does not, by itself, prove that a template lookup is fresh.
### Asset CDN

All merchant uploaded media assets and theme assets are loaded from our CDN for the fastest performance.
Expand All @@ -27,17 +29,32 @@ All pages on storefront are cached for 5 minutes to ensure popular pages are as


<Callout type="idea">
To skip the cache, you can append a unique querystring such as `?skip_cache` to skip existing cache and see the latest.
On the network domain or in an active preview session, append `?skip_cache=1` to bypass both the full-page and theme-template caches for that request. On a mapped production domain without a preview session, the parameter is ignored.
</Callout>
### Template Caching

Themes use many templates ie `layouts`, `partials`, and `assets` that when compiled together create amazing customer experiences. Templates are cached in memory to reduce database queries when compiling templates into the full html response.

Updating a template through the dashboard or [Theme Kit](/docs/storefront/themes/theme-kit) should automatically purge the cache for you to see your latest changes on the network domain, see notes above.
Each theme has a shared revision. Saving or deleting a template rotates that revision, so every application worker stops using its prior process-local or shared-cache entry. If a request must prove current database content, use the authorized `skip_cache=1` flow above.

Network-domain responses include diagnostic headers:

| Header | Meaning |
| --- | --- |
| `X-Theme-Id` | Active or previewed theme ID |
| `X-Theme-Template` | Effective template selected after fallback |
| `X-Theme-Template-Candidates` | Ordered custom and generic candidates |
| `X-Theme-Template-Revision` | Version of the selected template |
| `X-Theme-Revision` | Shared theme revision used for cache keys |
| `X-Theme-Cache` | `local`, `shared`, `db`, or `bypass-db` source |

These headers are intentionally omitted from mapped production domains. For a custom product page, verify that `X-Theme-Template` names the intended `product.<template-key>.html`; a product URL slug does not select the template.

Theme assets use one canonical storage key per logical asset name. Replacing an asset updates that key and its versioned URL rather than accumulating suffixed filenames.


<Callout type="warn">
There are a few cases wherein a form on the frontend needs to use a `{% csrf_token %}` field to secure submission to the backend. The platform core JS will automatically replace `{% csrf_token %}` that are in cached versions of pages to ensure the forms still work.

**It is advisable to not implement custom templates that require `{% csrf_token %}`, we recommend the [Storefront GraphQL API](/docs/storefront/graphql) instead.**
</Callout>
</Callout>
68 changes: 33 additions & 35 deletions content/docs/storefront/themes/guides/custom-product-templates.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,61 +6,59 @@ tags:
---
import { Callout } from 'fumadocs-ui/components/callout';

Products can have very diverse design requirements that often require custom layouts. In this guide, we'll go over some of the best practices for creating and managing custom product templates.
Products can have very different design requirements. Assign a named custom product template when a product needs a purpose-built layout.

### Product Templates Location
### Product Template Location

In the `templates/catalogue` directory of a theme, theme developers can edit/manage the product page templates.
Store product templates under `templates/catalogue`:

```bash title="Product Templates Location"
catalogue
└── product.html (default)
└── product.<custom1>.html
└── product.<custom2>.html
```text title="Product Templates Location"
templates/catalogue/
product.html
product.subscription.html
product.bundle.html
```

### Extend & Override
The segment between `product.` and `.html` is the product's template key. A product URL slug does not select the template.

**Create a Custom Product Template**
### Build a Standalone Product Document

Create a new product template in the **templates>catalogue** directory with the following naming convention:
Create the exact file for the key you plan to assign:

```bash title="Custom Product Template Naming"
templates/catalogue/product.<custom>.html
```text title="Custom Product Template Naming"
templates/catalogue/product.<template-key>.html
```

Templates that follow this naming convention will be selectable on the product detail to use on the storefront.


**Extend & Override Default Product Template**

As a best practice, you should [extend](/docs/storefront/themes/templates/tags#extends--block) the default product template to override the necessary [template blocks](/docs/storefront/themes/templates/tags#extends--block) to achieve your customization with a limited amount of duplicate code.
Do not extend `templates/catalogue/product.html` from a `product.<template-key>.html` file. Runtime template resolution already treats the generic template as a fallback; inheriting from it can hide selection mistakes and couples the custom design to a separate page implementation.

A custom product template may be a complete document or extend the shared `layouts/base.html` shell. Keep independently replaceable global surfaces in named [template blocks](/docs/storefront/themes/templates/tags#extends--block).

```django title="Example Custom Product Template"
{% extends "layouts/base.html" %}

{% extends "templates/catalogue/product.html" %}

{% block header %}
// Custom Product Header Code
{% endblock header %}

{% block product_description %}
// Custom Product Content Template Code
{% endblock %}

{% block title %}{{ product.title }}{% endblock title %}

{% block content %}
<article data-product-id="{{ product.id }}">
<h1>{{ product.title }}</h1>
{# Render the complete custom product experience here. #}
</article>
{% endblock content %}
```

This strategy will simplify the creation and management of custom product templates so you can focus on the customized areas for the new custom product template.
Validate and upload the exact file before assigning it:

```bash
ntk validate --server templates/catalogue/product.subscription.html
ntk push templates/catalogue/product.subscription.html --json --no-progress
```

**Select Template for Product**
### Assign and Verify the Template

On your product of choice, select your newly created template as the Product Template to activate the template on your product in the storefront.
On the product, set **Product Template** to the template key—for example, `subscription`. You can use the dashboard or the Admin API. Then open the product route in a preview session with `skip_cache=1`.

On the network domain, confirm `X-Theme-Template: templates/catalogue/product.subscription.html`. If the header reports `templates/catalogue/product.html`, the platform fell back to the generic template; check the product's template field, filename, validation result, and upload outcome.

<Callout type="idea">

You are not limited to overriding the existing template blocks in the default product template. You can create and add your own to the default template to overide in your custom template. For example, adding `{% block my_custom_block %}{% endblock %}` to product.html, around any area you wish to customize, will allow you to overide it in the custom template
</Callout>
Preview selection is pinned in the `preview_theme` cookie. Use the storefront preview indicator's **Exit preview** action or `/?deactivate-theme=true` when you finish; opening a plain URL does not deactivate the preview.
</Callout>
46 changes: 46 additions & 0 deletions content/docs/storefront/themes/guides/figma-to-theme.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
title: Figma-to-Theme Handoff
sidebar_label: Figma-to-Theme Handoff
tags:
- Guide
---
import { Callout } from 'fumadocs-ui/components/callout';

Use the [`next-theme-figma`](/docs/skills) skill to turn a storefront design into a low-inference handoff, then use `next-theme-dev` to implement it in a Spark-derived theme.

### Validate the Source Before Coding

Capture the exact Figma file and node IDs, inventory desktop and mobile frames, identify reusable sections, and map design tokens and assets. A large metadata response with an empty child list is a truncation or tooling failure, not proof that the frame is empty.

When a large file cannot be read reliably:

1. Query the known frame or component node directly.
2. Split a full page into smaller frame or section reads.
3. Export assets by exact node ID in bounded batches.
4. Retry selection synchronization no more than three times.
5. If tool access still fails and the owner authorizes it, use an exported `.fig` source.

Record unresolved gaps explicitly instead of inferring missing layout or asset details.

### Require Visual Evidence

Before declaring visual parity, keep both sides of the comparison:

- A matching Figma frame image for each reviewed route and viewport.
- A real storefront PNG for the same route and viewport.
- Desktop and mobile coverage, including responsive behavior and touch states.

Use Theme Kit for deterministic storefront capture:

```bash
ntk capture --url="/?preview_theme=<theme-id>&skip_cache=1" \
--output=qa-output --viewports=desktop,mobile --json --no-progress
```

<Callout type="warn">
DOM dimensions, text dumps, and screenshots of the wrong frame are diagnostics, not visual QA. If the matching Figma image cannot be obtained, stop the parity claim or record an accepted evidence gap with an owner.
</Callout>

### Preserve Route Coverage

Review every route in the handoff, not only the homepage. Product detail work must exercise the assigned custom product template, and every route must include a 1440px desktop and 390px mobile artifact before sign-off.
2 changes: 1 addition & 1 deletion content/docs/storefront/themes/guides/meta.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"title": "Guides",
"pages": ["custom-page-templates", "custom-product-templates", "product-variants"]
"pages": ["figma-to-theme", "custom-page-templates", "custom-product-templates", "product-variants"]
}
49 changes: 45 additions & 4 deletions content/docs/storefront/themes/theme-kit.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,19 @@ If you already have `python` and `pip`, install with the following command:
pip install next-theme-kit
```

The core CLI installs without native Sass bindings on macOS (including Apple Silicon), Linux, and native Windows. Install optional features only when needed:

```bash
pip install 'next-theme-kit[sass]' # legacy libsass compilation
pip install 'next-theme-kit[capture]' # screenshots; then run: playwright install chromium
```

#### Mac OSX Requirements
See how to install `python` and `pip` with [HomeBrew](https://docs.brew.sh/Homebrew-and-Python#python-3x). Once you have completed this step you can install using the `pip` instructions above.

#### Windows Requirements

* **Option 1 (Recommended)** - Windows 10 and above feature WSL (Windows Subsystem for Linux) which provides a native Linux environment, see how to [Install WSL with Ubuntu](https://docs.microsoft.com/en-us/windows/wsl/install). Once you have installed WSL, follow the [best practice guides to configure and use with VS Code](https://docs.microsoft.com/en-us/windows/wsl/setup/environment) and then follow the `pip` instructions above to install Theme Kit.

* **Option 2** - Installing `python` in Windows natively can be done with through the [Windows App Store](https://apps.microsoft.com/store/detail/python-39/9P7QFQMJRFP7?hl=en-us&gl=us). Recommend using [Windows Powershell](https://apps.microsoft.com/store/detail/powershell/9MZ1SNWT0N5D?hl=en-us&gl=us). This route is a little more tricky and some knowledge on how to manage python in windows will be required.
Theme Kit's core commands run in native Windows PowerShell as well as WSL. Install Python from [python.org](https://www.python.org/downloads/windows/) or the Windows App Store, create a virtual environment, then use the same `pip` command shown above.

<Callout type="idea">
**Use Python Virtual Environments** - For Mac, Windows, and Linux, it's a best practice to use a Python Virtual Environment to isolate python packages and dependencies to reduce potential conflicts or errors, [more on creating a Python Virtual Environment](https://www.freecodecamp.org/news/how-to-setup-virtual-environments-in-python/).
Expand All @@ -54,6 +59,8 @@ Store authentication uses [OAuth 2.0](https://auth0.com/intro-to-iam/what-is-oau
#### 2. Configure Theme Kit
`ntk` reads its connection settings from two places: command flags (`--apikey`, `--store`, `--theme_id`) and the `config.yml` file in your theme directory. You do not need to create `config.yml` by hand — `ntk checkout` and `ntk init` write it for you, and after that commands run without flags:

Store values are normalized to an absolute HTTPS origin. A bare hostname or `http://` value becomes `https://`; values containing a path, credentials, query string, fragment, or unsupported scheme fail immediately.

```yaml title="config.yml (written by ntk checkout / ntk init)"
development:
apikey: <api key>
Expand Down Expand Up @@ -96,6 +103,8 @@ With the package installed, you can now use the commands inside your theme direc
| `ntk push` | Push current theme state to store |
| `ntk watch` | Watch for local changes and automatically push changes to store |
| `ntk sass` | Process sass to css, see [Sass Processing](#sass-processing) |
| `ntk validate` | Validate theme files locally or against the store |
| `ntk capture` | Capture deterministic desktop and mobile PNGs |


#### Browse Store Themes
Expand Down Expand Up @@ -153,7 +162,7 @@ On success, `ntk init` logs the new theme ID and name, and persists the theme ID
To sync files between your local directory and the store, use `ntk push` to upload and `ntk pull` to download. Both upload or download the whole theme by default, and both accept file paths as positional arguments to limit the operation to specific files.

<Callout type="info">
File paths are relative to the theme root. `ntk push` only uploads files inside the theme directories (`assets`, `checkout`, `configs`, `layouts`, `locales`, `partials`, `sass`, `templates`) with valid theme file extensions — a path outside of them is skipped silently, not reported as an error.
File paths are relative to the theme root. `ntk push` only uploads files inside the theme directories (`assets`, `checkout`, `configs`, `layouts`, `locales`, `partials`, `sass`, `templates`) with valid theme file extensions. Explicit unsupported or missing paths are reported as rejected and make the command fail.
</Callout>

<Tabs items={['Push a single file', 'Push a subset of files', 'Pull a single file', 'Pull a subset of files']}>
Expand Down Expand Up @@ -196,6 +205,8 @@ ntk watch

On start, `ntk watch` logs the store, theme ID, a preview-theme URL, and the directory it is watching. Press `Ctrl + C` to stop.

Opening a plain storefront URL does not leave a pinned preview session. Use the visible preview indicator's **Exit preview** link or open `/?deactivate-theme=true`.

<Callout type="warn">
Deletes sync too — deleting a local file while `ntk watch` is running deletes that file from the theme on the store.
</Callout>
Expand All @@ -204,6 +215,36 @@ Deletes sync too — deleting a local file while `ntk watch` is running deletes
`ntk watch` watches the current directory tree (subdirectories included) and only uploads files with valid theme extensions. It does not accept file arguments. To scope changes to specific files, run `ntk push` with file paths instead.
</Callout>

#### Validate Before Upload

Local validation checks supported paths, JSON syntax, template block balance, and unsafe custom-product inheritance. It does not claim to prove a complete runtime render.

```bash
ntk validate templates/catalogue/product.subscription.html configs/settings.json
ntk validate --server templates/catalogue/product.subscription.html
```

`--server` submits locally valid text templates to the store validator without saving. It requires the store, API key, and theme ID from flags or `config.yml`.

#### Capture Desktop and Mobile Evidence

With the capture extra and Chromium installed, generate real rendered PNGs at the fixed 1440px desktop and 390px mobile widths:

```bash
ntk capture --url="/?preview_theme=<theme-id>&skip_cache=1" \
--output=qa-output --viewports=desktop,mobile --json --no-progress
```

Capture waits for network idle, web fonts, lazy content, and images. DOM measurements are useful diagnostics but are not a substitute for these visual artifacts.

#### Automation Contract

Finite commands accept `--json`, `--quiet`, and `--no-progress`. JSON mode writes exactly one schema-versioned result to stdout, keeps diagnostics on stderr, disables interactive progress, and reports file outcomes individually. Authentication, connection, validation, rejection, and partial-transfer failures return a non-zero exit status.

```json
{"schema_version":"1","command":"push","ok":true,"count":1,"results":[{"path":"templates/index.html","status":"uploaded"}]}
```

#### Sass Processing
Theme kit includes support for Sass processing via [Python Libsass](https://sass.github.io/libsass-python/). Sass processing includes support for variables, imports, nesting, mixins, inheritance, custom functions, and more.

Expand Down