Run on the nodesandbox runtime: harness toolchain, Hono server entry

The sandbox loads Vite's native tools as WASI (NAPI_RS_FORCE_WASI=error)
and only ships glue for rolldown 1.1.x. Vite 8.3 pulls rolldown 1.2.x,
whose binding needs emnapi 2.0 alpha, so boot failed with 'WASI binding
not found'. Match the runtime-host harness TanStack sample instead:

- Pin vite 8.1.3, rolldown + @rolldown/binding-wasm32-wasi 1.1.4,
  @vitejs/plugin-react 6.0.0, tailwindcss + @tailwindcss/vite 4.3.1
  (exact versions: the sandbox resolves package.json, not yarn.lock)
- Drop Nitro (it brings rolldown 1.2.x) and the Vercel config
- Hono now sits in src/server.ts, Start's server entry, routing /api/*
  ahead of start.fetch, as in the harness
- dev runs 'vite dev --host 0.0.0.0 --port 3000'; config is .mjs
- Await product recommendations in the loader to fix a hydration
  mismatch between the SSR skeleton and the settled client render

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Rami Bitar
2026-10-03 14:51:11 -04:00
co-authored by Claude Opus 5.5
parent 099ba454e0
commit e09bc0e1fe
11 changed files with 450 additions and 389 deletions
+21 -16
View File
@@ -1,14 +1,16 @@
# 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.
A server-rendered Shopify storefront built with Vite, TanStack Start (TanStack
Router + TanStack Query), Hono and Tailwind CSS v4. `@shopify/hydrogen` is used
only as the Storefront API client and for typed `gql()` documents. It's a port
of `nextjs-templates/shopify-storefront` without the AI store assistant.
Runs in the nodesandbox runtime: `npm install` → `npm run dev` → port 3000.
## Getting started
```sh
cp .env.example .env.local # defaults to the tokenless mock.shop
cp .env.example .env.local # optional; without it the store is mock.shop
corepack enable # uses the Yarn 4 pinned in package.json
yarn install
yarn dev # http://localhost:3000
@@ -16,26 +18,29 @@ 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 dev` | Vite dev server with SSR and the Hono `/api` routes |
| `yarn build` | Production build to `dist/` |
| `yarn typecheck` | `tsc` plus `hydrogen gql check` for the GraphQL documents |
## Deploying to Vercel
## nodesandbox compatibility
`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`.
The sandbox runs Vite's native tools as WebAssembly (`NAPI_RS_FORCE_WASI`), and
its installer resolves from `package.json` ranges rather than `yarn.lock`. So:
- `vite` is pinned to **8.1.3**, which uses rolldown 1.1.x; `rolldown` and
`@rolldown/binding-wasm32-wasi` are pinned to **1.1.4**. Rolldown 1.2.x's
WASI binding needs glue the runtime doesn't support ("WASI binding not
found"). Bump these only together with the runtime.
- `@vitejs/plugin-react` (6.0.0) and Tailwind (4.3.1) match the harness samples.
- No Nitro: it brings its own rolldown 1.2.x.
## Layout
```
src/
server.ts Start's server entry: Hono routes /api/*, the rest goes to Start
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
@@ -56,7 +61,7 @@ src/
| `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 |
| `NEXT_PUBLIC_*` env | `VITE_*` env (`VITE_SHOPIFY_DOMAIN` defaults to mock.shop) |
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