# Install Smootify in Astro by hand

> Add the Smootify integration to astro.config, set the options, connect the site id and check that the site runs.

Status: Ready (Smootify 2.0)  
URL: https://www.smootify.io/docs/astro/start/install  
Updated: 2026-10-21

Smootify for Astro is an Astro integration. It adds Smootify’s script to every page, reads your Shopify catalog into content collections, and writes the first load of each page into the HTML at build time. This page adds it to a project, explains each option and checks that it runs.

> [!NOTE]
> A project made with [Smootify Studio](https://www.smootify.io/docs/astro/start/studio-scaffold) already has all of this. Read this page to add Smootify to a project you already have, or to know what Studio wrote. You need Astro 7 and a site in the Smootify dashboard that is connected to your Shopify store.

## 1. Add the package

Add the integration with Astro’s own command. It installs `@smootify/astro` from npm and adds `smootify()` to `astro.config.mjs`:

```sh
npx astro add @smootify/astro
```

In a project that uses pnpm, run `pnpm astro add @smootify/astro` instead: the lockfile decides the package manager, never mix two. If the project has no Cloudflare adapter yet, add it the same way: `npx astro add cloudflare`.

## 2. Add the integration to astro.config

This is the config Studio writes for a project on Cloudflare:

```js
// astro.config.mjs
import { defineConfig } from "astro/config";
import smootify from "@smootify/astro";
import cloudflare from "@astrojs/cloudflare";

export default defineConfig({
  site: "https://shop.example.com",
  output: "static",
  trailingSlash: "always",
  adapter: cloudflare(),
  integrations: [smootify({ siteId: "<24-character Smootify site id>" })],
});
```

What each line does:

- **`site`** is the address the site is served from. Canonical links, `og:url` and the JSON-LD need it. Until the site has a domain, use `http://localhost:4321`.
- **`output: "static"`** builds every page ahead. Pages that read live data opt out of it one by one: see [Content from Shopify](https://www.smootify.io/docs/astro/start/content).
- **`trailingSlash: "always"`** makes every page address end with `/`. The static host answers `/products/shirt/` and redirects `/products/shirt`, so links, canonical addresses and the sitemap must all use the address that answers. Smootify reads this setting and writes its own links with the slash.
- **`adapter`** is `@astrojs/cloudflare`. Smootify’s hosting is Cloudflare: see [Deploy to Cloudflare](https://www.smootify.io/docs/astro/start/deploy).
- **`smootify({ siteId })`** is the integration.

## 3. Set the site id

`siteId` is the 24-character id of your site in Smootify. The integration reads the store and the public Storefront token from it, at build time. The token is never written into your pages.

Instead of the option, you can set the `SMOOTIFY_SITE_ID` environment variable. In a project made by Studio, the id sits in one file, `smootify.config.mjs`, which the config and the content collections both read.

## 4. Options

`smootify()` takes these options. Only `siteId` is required.

| Option | Default | What it does |
|---|---|---|
| `siteId` | `SMOOTIFY_SITE_ID` | The Smootify site id. |
| `channel` | none | Which release of Smootify the pages load, written as `data-channel` on the script tag. |
| `userOptions` | none | The `window.SmootifyUserOptions` of every page. |
| `seed` | `true` | Writes the first load of each page into its HTML at build time. See [First load](https://www.smootify.io/docs/astro/start/first-load). `false` turns it off. |
| `locales` | off | `true`, or `{ languages, markets, paths }`: one page per market and language, with Shopify’s URL scheme. |
| `sitemap` | on | Writes `sitemap.xml` and, when the project has none, `robots.txt` at build time. `{ exclude, extraUrls }` changes the list, `false` turns it off. Needs `site`. See [SEO and structured data](https://www.smootify.io/docs/astro/start/seo). |
| `webhook` | off | `true`, or `{ debounce }` in seconds: the route that Shopify’s webhooks call. See [Deploy to Cloudflare](https://www.smootify.io/docs/astro/start/deploy). |
| `types` | `true` | Adds types for Smootify’s attributes (`product="title"`), so `astro check` accepts them. |
| `inject` | `true` | Adds the script to every page. With `false`, put `<SmootifyScript />` in your own `<head>`. |
| `runtimeUrl` | Smootify’s CDN | Replaces the address of the script, for a local build of Smootify. |
| `runtimeCssUrl` | next to the script | The runtime stylesheet. `false` leaves it out, for a site that ships those rules itself. |

For the `locales` and `webhook` options, the details are in the pages that use them. Smootify’s own options, such as the URLs of your product pages, go in `userOptions`:

```js
smootify({
  siteId: "<24-character Smootify site id>",
  userOptions: { productsBase: "shop", collectionsBase: "categories", vendorsBase: "brands" },
});
```

Smootify writes them before its script, and the build uses them too: the links and prices drawn at build time, and the sitemap’s on-demand pages, follow the same options. Put every option the page depends on here, not in a script of your own. The default routes are plural: `/products/<handle>`, `/collections/<handle>` and `/vendors/<handle>`. If you use other names, name the page folders the same way and set the three bases here.

With `trailingSlash: "always"`, Smootify sets its own `trailingSlash` option to `true`. Your own value in `userOptions` wins.

## 5. Plans and domains

The plans are the same as for every Smootify site:

- **Free** works on `localhost` and on `*.workers.dev` addresses, and shows the Smootify badge.
- **Lite** is the production licence: your registered domain needs it. It includes every client element.
- **Server** adds the server add-ons, on the licensed domain.

Add the domain of the site in the Smootify dashboard before you go live on it.

## 6. Check that it runs

1. Run `pnpm dev`. The site runs at `http://localhost:4321`.
2. Open a page, then the browser’s Network panel. The page loads `loader.js` from `cdn.smootify.io`.
3. Run `pnpm build`. The log has a line that starts with `seed:`, with the number of pages seeded.

If the build ends with an error that names `siteId`, the id is missing or is not 24 characters of lower-case hexadecimal.

## Before you publish

> [!STUCK]
> - **The build stops with a `siteId` error.** The option is missing, or the environment variable `SMOOTIFY_SITE_ID` is not set where the build runs. The id is 24 lower-case hexadecimal characters.
> - **A loader fails with `ACCESS_DENIED`.** The Storefront token of the site lacks a scope. The error names it. Blogs, articles and pages need `unauthenticated_read_content`, which the Smootify token does not have: pass your own `store` and `storefrontToken` to those loaders.
> - **Smootify's links go to `/product/…` and the page is not found.** Your folders use other names than the defaults. Set `productsBase`, `collectionsBase` and `vendorsBase` in `userOptions` to match.
> - **A condition such as `condition="out-of-stock"` shows at the wrong time on first paint.** The runtime stylesheet is left out. Do not set `runtimeCssUrl: false` unless the site has those rules.
> - **The build warns that the seed was skipped.** Smootify's seed builder could not be downloaded. The site still works: Smootify asks Shopify at load instead. Check the network of the build machine.
