All four paths use the same tags. The choice is only about who renders the first HTML:
- Plain HTML: one script tag; data is fetched in the browser. Works inside any framework too.
- Astro / Next.js / React SSR: the framework package server-renders the tags with real Shopify data, and the client runtime adopts the output without refetching.
If your site already server-renders, use the matching package. Converting an existing site? See Converting existing HTML. Every path needs the credentials from Connect your store.
Plain HTML
Section titled “Plain HTML”Load the bundle from the CDN. The 0.1 path is a rolling channel:
<script type="module" src="https://cdn.storesynk.io/elements/0.1/storesynk.js"></script>To pin an exact version, use https://cdn.storesynk.io/elements/<x.y.z>/storesynk.js. To self-host, install @storesynk/elements@beta and copy the package’s entire dist/ folder into your site; storesynk.js loads its sibling chunks relative to its own URL.
Wrap the storefront in one <storesynk-store>. Site-global settings can live in one inert JSON block:
<storesynk-store domain="your-store.myshopify.com" token="your-public-storefront-token"> <!-- Optional: site-global defaults in one inert JSON block. --> <script type="application/json" data-storesynk-config> { "cart": { "closeOnOutside": true } } </script>
<!-- your storefront --></storesynk-store>
<script type="module" src="https://cdn.storesynk.io/elements/0.1/storesynk.js"></script>A tag attribute always overrides the config block. A script that sets domain/token must run before the bundle script.
Full path guide: Plain HTML.
@storesynk/astro server-renders at build time, or per request with an SSR adapter, and injects the runtime on every page. Supports Astro 5–7.
npm install @storesynk/astro@betanpx @storesynk/astro init # writes an annotated storesynk.config.tsimport { defineConfig } from 'astro/config';import storesynk from '@storesynk/astro';import storesynkConfig from './storesynk.config';
export default defineConfig({ integrations: [storesynk(storesynkConfig)],});storesynk.config.ts holds the connection (read domain/token from the env names below) and every optional behavior group. In pages, write plain tags inside the wrappers:
---import { StoresynkStore, StoresynkProduct } from '@storesynk/astro/components';---<StoresynkStore> <StoresynkProduct handle="your-product-handle"> <show-title></show-title> <show-price></show-price> <add-to-cart><button type="button">Add to cart</button></add-to-cart> </StoresynkProduct></StoresynkStore>The integration writes <storesynk-store> and the bundle script for you. Full path guide: Astro.
Next.js (App Router)
Section titled “Next.js (App Router)”@storesynk/next requires Next 15+, React 19+, and the App Router.
npm install @storesynk/next@betanpx @storesynk/next init # writes an annotated storesynk.config.tsCredentials go in env:
SHOPIFY_STORE_DOMAIN="your-store.myshopify.com"SHOPIFY_STOREFRONT_ACCESS_TOKEN="your-public-storefront-token"Everything else is in storesynk.config.ts:
import { configureStoresynk } from '@storesynk/next';
configureStoresynk({ // domain/token are inherited from env - this file is just behavior: country: 'US', cart: { openOnAdd: true },});Import it for its side effect at the very top of app/layout.tsx, and put <StoresynkStore> in the root layout so the cart survives navigation:
import '../storesynk.config';Children of <StoresynkProduct> / <StoresynkList> must be static host elements: plain tags, no client components, no React state. Full path guide: Next.js.
React SSR (TanStack Start, Remix / React Router)
Section titled “React SSR (TanStack Start, Remix / React Router)”@storesynk/react is the framework-agnostic sibling of @storesynk/next for classic-SSR React stacks.
npm install @storesynk/react@betanpx @storesynk/react init # writes an annotated storesynk.config.tsCredentials use the same env names as Next.js. Import storesynk.config.ts for its side effect at the top of your root module (TanStack Start: the router/root route module; Remix: app/root.tsx).
Classic-SSR components render twice and cannot be async, so the async work runs in your data layer: a loader calls renderStore / renderProduct from @storesynk/react/server, and the synchronous components take the result via a prepared prop:
export const loader = async ({ params, request }: LoaderFunctionArgs) => { const opts = { request, fresh: true, scope: createRequestScope() }; return { store: await renderStore(opts), product: await renderProduct(<ProductTemplate />, { handle: params.handle!, ...opts }), };};Templates handed to the render* helpers are the same static host elements as in Next.js. Full path guide: React SSR.
Environment variables
Section titled “Environment variables”Only the two credentials live in env:
| Variable | Value |
|---|---|
SHOPIFY_STORE_DOMAIN | your-store.myshopify.com |
SHOPIFY_STOREFRONT_ACCESS_TOKEN | the public Storefront token - never an Admin token |
STORESYNK_STORE_DOMAIN / STORESYNK_PUBLIC_TOKEN are accepted as explicit overrides. Locale, cart behavior, and pixels belong in storesynk.config.ts (or the data-storesynk-config block), not in env.
Pinning versions
Section titled “Pinning versions”The packages are published under the @beta dist-tag at 0.1.0-beta.8. Pre-1.0, a minor bump can contain breaking changes: pin exact versions (--save-exact) and commit the lockfile. See Go live.
Next: Core concepts