Vercel auto-detected the Hydrogen preset from the @shopify/hydrogen dependency and failed building a 'hydrogen' Edge Function. The app is now TanStack Start (SSR via Nitro), and vercel.json pins the tanstack-start preset and installs with Corepack so Yarn 4 is used. - Router factory with per-request QueryClient and SSR query dehydration - Hono API mounted as a Start server route at /api/* - Account reads in loaders go through server functions (cookies on SSR) - Loaders prefetch listing pages so products are in the server HTML - Add graphql peer dependency for gql.tada Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Vite Shopify Storefront
A server-rendered Shopify storefront built with TanStack Start (Vite + TanStack
Router), TanStack Query, Tailwind CSS v4, Hono and @shopify/hydrogen (used
only as a Storefront API client and typed gql()). It's a port of
nextjs-templates/shopify-storefront without the AI store assistant.
Getting started
cp .env.example .env.local # defaults to the tokenless mock.shop
corepack enable # uses the Yarn 4 pinned in package.json
yarn install
yarn dev # http://localhost:3000
| Script | What it does |
|---|---|
yarn dev |
Vite dev server with SSR and the /api routes |
yarn build |
Production build via Nitro (.output/, or Vercel's Build Output on Vercel) |
yarn start |
Run the Node build from .output/ |
yarn typecheck |
tsc plus hydrogen gql check for the GraphQL documents |
Deploying to Vercel
vercel.json pins the TanStack Start preset. Without it Vercel's
auto-detection sees @shopify/hydrogen and picks the Hydrogen preset. It also
installs with Corepack so Vercel uses Yarn 4. Set the VITE_SHOPIFY_* variables
in the project; the production domain is picked up for canonical URLs
automatically, or set VITE_SITE_URL.
Layout
src/
router.tsx Router + per-request QueryClient, SSR query integration
routes/ File routes; loaders prefetch into TanStack Query
api/$.ts Mounts the Hono app for every /api/* request
server/
app.ts Hono API
account.ts login, logout, register, recover, reset, activate, me
account.functions.ts server functions for account reads in loaders
hooks/ TanStack Query options + hooks over the Storefront API
services/shopify Storefront client, catalogue and customer functions
graphql/ Typed `gql()` documents
components/ Storefront UI (header, cart drawer, product detail, ...)
How the Next.js pieces map
| Next.js | Here |
|---|---|
app/**/page.tsx |
src/routes/** (TanStack file routes) |
generateMetadata / metadata |
route head() via src/lib/seo.ts, server-rendered |
| Server components fetching data | route loaders seeding TanStack Query, dehydrated to the client |
app/api/account/* route handlers |
src/server/account.ts (Hono) |
next/headers cookies |
hono/cookie, and getCookie in server functions |
next/image |
src/components/ui/image.tsx (Shopify CDN srcset) |
NEXT_PUBLIC_* env |
VITE_* env |
Cart and catalogue reads after the first page load go straight from the browser to the Storefront API with the public token. Account requests stay on the server, so the customer access token never reaches client JavaScript.