Set up Joinery and Fitting Room for Astro

This guide is for buyers of Joinery or Fitting Room for Astro who are preparing their own shop. Use GETTING-STARTED.md and EMDASH.md in your download as the full references for configuration, product fields and the optional content-source switch.

Before you start

Use Node 24 LTS or Node 22 LTS, version 22.19.0 or later. Both templates pin Astro 7.3.3 in the lockfile. You need a code editor, a terminal, a static host and an account with the payment provider you will use. The optional cart additionally needs a host that runs server code. EmDash needs hosting that runs Node.

Keep a backup of the extracted source before editing. The demo shops, products, prices and SKUs are fictional. The Shipping, Returns and Privacy pages are marked samples and need text for your business.

Install and run the template

  1. Extract the ZIP and open a terminal in the extracted project folder containing package.json.
  2. Install the locked dependencies with the following command.
npm ci
  1. Start the development server and open the address Astro prints in the terminal.
npm run dev
  1. After editing, run the checks, tests and build in this order.
npm run check
npm test
npm run build
  1. For the default static site, upload the resulting dist/ folder to your static host with its normal 404 handling.

Publish at the root of a domain. Subdirectory hosting is not supported by the discovery setup. Both templates pass these commands with shipped demo content on Node 22.23.2 and Node 24.21.0; the check reports 0 errors and 0 warnings. Run them again for your own content and configuration.

Make it yours

Open src/site.config.ts and set identity.name to your shop name. This changes the header, footer, page titles and structured data. Set url to your HTTPS origin, then edit the description, contact email, locale, nav and footer columns. Review the home page wording, photographs and section headings.

Set your palette in theme.colors and your display and body font stacks in theme.fonts. Both templates use fonts installed on visitors’ devices and bundle no font files. Joinery includes a clay color alongside its workshop green accent; Fitting Room uses a signal red accent.

You can change the credit in footer.attribution or hide it with show: false. Delete footer.note when your shop replaces the demo. Replace all demo copy and photographs, including the sample policy text; remove sample: true from a policy page after rewriting it.

Add your products

Create or edit Markdown files in src/content/products/. The file name sets the product address, so renaming a file changes its URL. Write the full product description below the front matter.

Fields What you edit
title and description These set the name and short summary used by cards, search and page descriptions.
price, compareAt and currency These set the displayed price, optional higher old price and currency; currency otherwise comes from commerce.currency.
sku and available These set an optional stock code and availability; false leaves the page visible but marks the item sold out.
checkoutUrl and stripePriceId These set a hosted checkout link or an optional existing Stripe Price for cart purchases.
images, categories and tags These connect photo keys, category file names and searchable tags to the product.
order and date These set catalog order and the release date used by the Newest sort.
draft, unlisted and noindex These control publication and discovery as described in DISCOVERY.md.

For choices such as size, use optionNames with at most two names and a variants row for each choice. Each row has values and can have its own price, compareAt, sku, checkoutUrl and available value. With variants, put checkout links on individual variants rather than the product. Cart variants can also have stripePriceId.

Joinery products have material, finish and leadTime specifications. The lead time also appears on product cards, and process can select a workshop photograph shown beside the piece on the home page. Fitting Room uses details rows with label and value, such as Fabric and Care, plus looks entries naming the look files in which a product appears.

Categories live in src/content/categories/ and have name, description, optional summary and order. Empty categories are omitted from filters and the home page. Fitting Room looks live in src/content/looks/; their products follow product order.

Put photographs in src/assets/photos/ and register them in src/data/photos.json with file, alt, creator, provider, source, license and licenseUrl. Products use those registered keys, with the first image as the main photograph. Remove unused demo entries and update ASSETS.json. Invalid field types, unknown references and mismatched variants stop the checks and build with an explanation.

Sell with checkout links (default)

Stripe Payment Links

  1. In the Stripe Dashboard, create the product and its price, matching the amount and currency shown in your catalog.
  2. Create a Payment Link for that product. If you ship physical goods, turn on shipping-address collection and shipping rates.
  3. Paste the https link beginning with https://buy.stripe.com/… into checkoutUrl for the product or each variant.
  4. Test each link in Stripe test mode before publishing, including each variant’s price and availability.

The Buy button opens the provider’s checkout page. The provider takes payment and keeps the order; your site remains static. Product pages identify recognized checkout providers below the button.

Lemon Squeezy, Polar and Shopify links

For Lemon Squeezy, create the product and variants and use the variant’s checkout link. For Polar, create the product and a checkout link. Lemon Squeezy suits digital products and software licenses, and Polar suits digital products and downloads. Shopify checkout links or cart permalinks can point to a product variant. Paste the provider’s HTTPS link into the same checkoutUrl field.

Restrict checkout hosts and finish provider setup

List permitted host names in commerce.allowedCheckoutHosts if you want to restrict checkout destinations. A link on another host then stops the build. All checkout links must use HTTPS.

Keep the provider’s price and currency equal to the displayed values. Configure taxes, shipping rates, address collection, stock limits, confirmation emails or download delivery, refunds and the success page with your provider. The template does not configure these for you. Links left on example.com show a “Demo link” notice and do not take payments.

Turn on the optional cart (Stripe Checkout)

  1. Add a server adapter so /api/checkout can run. Choose one of the four documented commands below. The Node adapter was tested; the Cloudflare, Vercel and Netlify adapters were not tested.

For Node, use this command.

npx astro add node

For Cloudflare, the documented command is the following.

npx astro add cloudflare

For Vercel, the documented command is the following.

npx astro add vercel

For Netlify, the documented command is the following.

npx astro add netlify
  1. Set commerce.cart.enabled: true in src/site.config.ts. Set allowedCountries to two-letter shipping country codes, or [] to request no address for digital goods. Set shippingRates to your Stripe shipping rate IDs, maxQuantity to your quantity limit, and automaticTax only after configuring Stripe Tax.
  2. Remove checkoutUrl from products or variants sold through the cart. Optionally set stripePriceId to an existing price_… ID, on each variant when variants exist. Otherwise the route uses the price in your product content.
  3. Set STRIPE_SECRET_KEY as an environment variable on the host. Never put it in a file in the repository. A restricted rk_… key with write access to Checkout Sessions is enough.
  4. Test first with an sk_test_… key. Add items, change quantities and check out with card 4242 4242 4242 4242, any future date and any CVC. Confirm the paid order in the Stripe Dashboard in test mode and the return to /checkout/success/.
  5. After those checks, replace the test key with your live key in the host’s environment.

The route determines prices on the server. On October 2, 2026, a full test-mode payment through the Joinery cart on localhost used the Node adapter, @astrojs/node 11.1.6, and paid the server-side prices. Bad quantities, unknown products, a foreign origin and a client-sent price were refused. Fitting Room uses the same cart code. The cart does not track stock or store orders; Stripe tells you about paid orders, and fulfillment is your responsibility.

Use EmDash as the content source (optional)

EmDash replaces Markdown content with database content and server rendering on Node. Its admin is at /_emdash/admin. Site-wide settings stay in src/site.config.ts. Follow these four steps, with EMDASH.md open for the full details.

  1. Install the dependencies, then add an emdash entry to package.json with label set to Joinery or Fitting Room and seed set to emdash/seed.json, as shown in EMDASH.md.
npm install emdash@1.0.1 @astrojs/node @astrojs/react react react-dom
  1. Copy the supplied configuration files.
cp emdash/astro.config.emdash.ts astro.config.ts
cp emdash/live.config.ts src/live.config.ts

The configuration uses data.db and uploads/. Add data.db* and uploads/ to .gitignore and back them up.

  1. Copy the content source, body renderer and sitemap files, then set the source import in src/lib/content.ts to import * as source from './source/emdash';.
mkdir -p src/lib/source
cp emdash/source.emdash.ts src/lib/source/emdash.ts
cp emdash/Body.astro src/components/Body.astro
cp emdash/pages/sitemap.xml.ts "emdash/pages/sitemap-[collection].xml.ts" src/pages/
rm "src/pages/[file].xml.ts"
  1. Seed the collections and demo content, start the development server and finish EmDash’s account setup at the admin path.
npx emdash seed emdash/seed.json
npm run dev

The cart still works with this configuration when you supply its settings, key and product changes. EmDash itself adds no cart. Content edits appear on the next request; code and configuration edits still require a build and deployment.

To switch back, restore astro.config.ts, src/components/Body.astro and src/pages/[file].xml.ts from version control. Restore the ‘./source/files’ import and delete src/live.config.ts and the two added sitemap files. EmDash content is not automatically exported to Markdown.

These steps were run with emdash 1.0.1 as described in EMDASH.md, including seed loading and content checks. The EmDash admin screens were not reviewed.

Publish and cache

Upload dist/ for a static shop, or deploy the server build for the cart or EmDash. After building a Node server, run it with the following command.

node dist/server/entry.mjs

Set /_astro/* to Cache-Control: public, max-age=31536000, immutable. Set HTML pages, /rss.xml, /sitemap.xml and /search.json to Cache-Control: public, max-age=0, must-revalidate. Never cache /api/checkout; the route already sends Cache-Control: no-store. Follow your host’s configuration method for these rules.

Where to get help

Use the Support page and FAQ, together with the references in your ZIP. Hosting, payment-provider setup and custom development are not included with the template.