Update to Netlify
Snapshot Oct 7, 2026 · 00:02 UTC · version 1.6.0
Collection source: downloaded plugin package. These snapshots do not have a confirmed matching collection source. Differences in file lists alone do not establish changes to the package.
Instructions updated for netlify-frameworks
Instruction wording changed from “Guide for deploying web frameworks on Netlify. Use when setting up a framework project (Vite/React, Astro, TanStack Start, Next.js, Nuxt, SvelteKit, Remix) for Netlify deployment, configuring adapters or plugins, or troubleshooting frame...” to “Deploy and configure web frameworks on Netlify — build settings and SSR/edge adapters plus local platform emulation and env vars. Use when setting up or fixing a framework deploy (Next.js / Astro / Nuxt / SvelteKit / Remix / React Router...”. 192 additional added or edited lines are in the evidence.
Observed in instructions or declared skills. Runtime behavior has not been tested.
Product description
Guide for deploying web frameworks on Netlify. Use when setting up a framework project (Vite/React, Astro, TanStack Start, Next.js, Nuxt, SvelteKit, Remix) for Netlify deployment, configuring adapters or plugins, or troubleshooting frame...
Deploy and configure web frameworks on Netlify — build settings and SSR/edge adapters plus local platform emulation and env vars. Use when setting up or fixing a framework deploy (Next.js / Astro / Nuxt / SvelteKit / Remix / React Router...
Skill instructions
Guide for deploying web frameworks on Netlify. Use when setting up a framework project (Vite/React, Astro, TanStack Start, Next.js, Nuxt, SvelteKit, Remix) for Netlify deployment, configuring adapters or plugins, or troubleshooting frame...
Deploy and configure web frameworks on Netlify — build settings and SSR/edge adapters plus local platform emulation and env vars. Use when setting up or fixing a framework deploy (Next.js / Astro / Nuxt / SvelteKit / Remix / React Router...
Supporting files
[{"relative_path":"LICENSE.txt","size_in_bytes":10776},{"relative_path":"agents/openai.yaml","size_in_bytes":353},{"relative_path":"assets/netlify-small.svg","size_in_bytes":1291},{"relative_path":"assets/netlify.png","size_in_bytes":268...
[{"relative_path":"references/astro.md","size_in_bytes":4730},{"relative_path":"references/nextjs.md","size_in_bytes":4555},{"relative_path":"references/nuxt.md","size_in_bytes":1556},{"relative_path":"references/sveltekit.md","size_in_b...
Compare saved observations
Download comparison JSONFull technical diff · 3 changed fields
changed /description
"Guide for deploying web frameworks on Netlify. Use when setting up a framework project (Vite/React, Astro, TanStack Start, Next.js, Nuxt, SvelteKit, Remix) for Netlify deployment, configuring adapters or plugins, or troubleshooting framework-specific Netlify integration. Covers what Netlify needs from each framework and how adapters handle server-side rendering."
"Deploy and configure web frameworks on Netlify — build settings and SSR/edge adapters plus local platform emulation and env vars. Use when setting up or fixing a framework deploy (Next.js / Astro / Nuxt / SvelteKit / Remix / React Router / TanStack Start / SolidStart / Gatsby / Angular / Vite / Express / Hydrogen / Hugo / Eleventy / Vue / React), adding SSR or edge functions or middleware wired to Netlify context, fixing SPA redirect and catch-all rules, setting a build command or publish directory, or debugging \"why isn't my env var updating\" and framework build failures."
changed /included_files
[
{
"relative_path": "LICENSE.txt",
"size_in_bytes": 10776
},
{
"relative_path": "agents/openai.yaml",
"size_in_bytes": 353
},
{
"relative_path": "assets/netlify-small.svg",
"size_in_bytes": 1291
},
{
"relative_path": "assets/netlify.png",
"size_in_bytes": 2686
},
{
"relative_path": "references/astro.md",
"size_in_bytes": 3066
},
{
"relative_path": "references/nextjs.md",
"size_in_bytes": 2425
},
{
"relative_path": "references/tanstack.md",
"size_in_bytes": 1449
},
{
"relative_path": "references/vite.md",
"size_in_bytes": 2406
}
][
{
"relative_path": "references/astro.md",
"size_in_bytes": 4730
},
{
"relative_path": "references/nextjs.md",
"size_in_bytes": 4555
},
{
"relative_path": "references/nuxt.md",
"size_in_bytes": 1556
},
{
"relative_path": "references/sveltekit.md",
"size_in_bytes": 2114
},
{
"relative_path": "references/tanstack.md",
"size_in_bytes": 2943
},
{
"relative_path": "references/vite.md",
"size_in_bytes": 3216
}
]changed /skill_md_contents
"---\nname: netlify-frameworks\ndescription: Guide for deploying web frameworks on Netlify. Use when setting up a framework project (Vite/React, Astro, TanStack Start, Next.js, Nuxt, SvelteKit, Remix) for Netlify deployment, configuring adapters or plugins, or troubleshooting framework-specific Netlify integration. Covers what Netlify needs from each framework and how adapters handle server-side rendering.\n---\n\n# Frameworks on Netlify\n\nNetlify supports any framework that produces static output. For frameworks with server-side capabilities (SSR, API routes, middleware), an adapter or plugin translates the framework's server-side code into Netlify Functions and Edge Functions automatically.\n\n## How It Works\n\nDuring build, the framework adapter writes files to `.netlify/v1/` — functions, edge functions, redirects, and configuration. Netlify reads these to deploy the site. You do not need to write Netlify Functions manually when using a framework adapter for server-side features.\n\n## Detecting Your Framework\n\nCheck these files to determine the framework:\n\n| File | Framework |\n|---|---|\n| `astro.config.*` | Astro |\n| `next.config.*` | Next.js |\n| `nuxt.config.*` | Nuxt |\n| `vite.config.*` + `react-router` | Vite + React (SPA or Remix) |\n| `app.config.*` + `@tanstack/react-start` | TanStack Start |\n| `svelte.config.*` | SvelteKit |\n\n## Framework Reference Guides\n\nEach framework has specific adapter/plugin requirements and local dev patterns:\n\n- **Vite + React (SPA or with server routes)**: See [references/vite.md](references/vite.md)\n- **Astro**: See [references/astro.md](references/astro.md)\n- **TanStack Start**: See [references/tanstack.md](references/tanstack.md)\n- **Next.js**: See [references/nextjs.md](references/nextjs.md)\n\n## General Patterns\n\n### Client-Side Routing (SPA)\n\nFor single-page apps with client-side routing, add a catch-all redirect:\n\n```toml\n# netlify.toml\n[[redirects]]\nfrom = \"/*\"\nto = \"/index.html\"\nstatus = 200\n```\n\n### Custom 404 Pages\n\n- **Static sites**: Create a `404.html` in your publish directory. Netlify serves it automatically for unmatched routes.\n- **SSR frameworks**: Handle 404s in the framework's routing (the adapter maps this to Netlify's function routing).\n\n### Environment Variables in Frameworks\n\nEach framework exposes environment variables to client-side code differently:\n\n| Framework | Client prefix | Access pattern |\n|---|---|---|\n| Vite / React | `VITE_` | `import.meta.env.VITE_VAR` |\n| Astro | `PUBLIC_` | `import.meta.env.PUBLIC_VAR` |\n| Next.js | `NEXT_PUBLIC_` | `process.env.NEXT_PUBLIC_VAR` |\n| Nuxt | `NUXT_PUBLIC_` | `useRuntimeConfig().public.var` |\n\nServer-side code in all frameworks can access variables via `process.env.VAR` or `Netlify.env.get(\"VAR\")`.\n\n## Bundled References (Load As Needed)\n\n- [Vite + React guide](references/vite.md)\n- [Astro guide](references/astro.md)\n- [TanStack Start guide](references/tanstack.md)\n- [Next.js guide](references/nextjs.md)\n"
"---\nname: netlify-frameworks\ndescription: Deploy and configure web frameworks on Netlify — build settings and SSR/edge adapters plus local platform emulation and env vars. Use when setting up or fixing a framework deploy (Next.js / Astro / Nuxt / SvelteKit / Remix / React Router / TanStack Start / SolidStart / Gatsby / Angular / Vite / Express / Hydrogen / Hugo / Eleventy / Vue / React), adding SSR or edge functions or middleware wired to Netlify context, fixing SPA redirect and catch-all rules, setting a build command or publish directory, or debugging \"why isn't my env var updating\" and framework build failures.\n---\n\nRoute framework-specific deep work to the guides in this skill: `references/astro.md`, `references/nextjs.md`, `references/nuxt.md`, `references/sveltekit.md`, `references/tanstack.md`, `references/vite.md`.\n\n## Env vars: modern rules (read first)\n\nEnv values are injected **at build time**. Any change (client- or server-side) requires a **redeploy** — editing a var in the UI/CLI does NOT reach the live site or already-deployed functions until a new build runs.\n\n**Never use a client prefix for secrets.** Client-prefixed vars are inlined into the browser bundle:\n`VITE_`, `NEXT_PUBLIC_`, `PUBLIC_`, `NUXT_PUBLIC_`, `REACT_APP_`, `GATSBY_`, `VUE_APP_`.\n\nClient-embed prefixes by framework: CRA `REACT_APP_`, Gatsby `GATSBY_`, Next `NEXT_PUBLIC_`, Nuxt `NUXT_ENV_`, Vue CLI `VUE_APP_`.\n\n**Scopes:** build-time access needs **Builds** scope; SSR/DSG runtime access needs **both Functions and Builds**. `netlify.toml` is read only during build — functions cannot read it at runtime; set runtime vars in UI/CLI/API.\n\nNetlify build variables can't be used as values in the UI or `netlify.toml` env sections. Set them inline before the build command:\n```toml\n[build]\n command = \"REACT_APP_CONTEXT=$CONTEXT npm run build\"\n```\n\n## SPA redirects and the SSR catch-all footgun\n\nSPAs (React, Vue CLI, Vite, Nuxt in SPA mode) need a rewrite to serve `index.html` for `pushState`:\n```\n/* /index.html 200\n```\n\n**Remove any SPA catch-all when adopting an SSR adapter.** A leftover `/* → /index.html 200` silently serves static `index.html` for SSR pages and API routes — user redirects beat adapter-generated routes.\n\n## Local dev with platform emulation (no Netlify CLI)\n\nVite-based frameworks emulate Netlify primitives (functions, edge functions, blobs, Netlify Database, Cache API, Image CDN, redirects/rewrites, headers, env vars, AI Gateway) in the dev server:\n\n| Framework | Plugin/module | Run |\n|-----------|---------------|-----|\n| Astro (5.12+) | built-in (Netlify Vite plugin auto-loaded) | `astro dev` |\n| Nuxt | `@netlify/nuxt` | `nuxt dev` |\n| React Router | `@netlify/vite-plugin` | `react-router dev` |\n| SolidStart 2 | `@netlify/vite-plugin` | `vite dev` |\n| TanStack Start | `@netlify/vite-plugin-tanstack-start` | (vite) |\n| Vite | `@netlify/vite-plugin` | `npx vite` |\n\nStill need `netlify dev` (Netlify CLI) for: Gatsby generated functions (run `netlify build` first), Angular SSR local test (`netlify serve`), and frameworks without a Vite plugin.\n\n**`netlify dev` gotcha:** with both a custom `command` and a `targetPort` in `[dev]`, you must set `framework = \"#custom\"` — otherwise the detector runs and your custom command is silently ignored.\n\n## Build settings by framework\n\n| Framework | Build command | Publish |\n|-----------|---------------|---------|\n| Angular (standard) | `ng build --prod` | `dist/YOUR_PROJECT_NAME` |\n| Astro | `astro build` | `dist` |\n| Create React App | `react-scripts build` | `build` |\n| Eleventy | `eleventy` | `_site` |\n| Gatsby | `gatsby build` | `public` |\n| Hugo | `hugo` | `public` |\n| Hydrogen | `remix vite:build` | `dist/client` |\n| Next.js (SSR/hybrid) | `next build` | `.next` |\n| Next.js (static export) | `next build && next export` | `out` (`NETLIFY_NEXT_PLUGIN_SKIP=true`) |\n| Nuxt 3 | `nuxt build` | `dist` |\n| Nuxt 2 | `nuxt generate` | `dist` |\n| React Router | `react-router build` | `build/client` |\n| Remix (Vite) | `remix vite:build` | `build/client` |\n| SolidStart 2 (Vite plugin) | `vite build` | `dist/client` |\n| SolidStart 2 (Nitro) | `vite build` | `dist` |\n| SolidStart 1.x | `vinxi build` | `dist` |\n| SvelteKit | `vite build` | `build` |\n| TanStack Start (1.132.0+) | `vite build` | `dist/client` |\n| Vite | `vite build` | `dist` |\n| Vue CLI | `vue-cli-service build` | `dist` |\n\nDetection suggests these; override in `netlify.toml` or UI (project configuration > Build & deploy > Continuous deployment > Build settings).\n\n## SSR / adapter setup\n\n### Astro\n`npx astro add netlify` installs the adapter and edits `astro.config.mjs`. Adapter needed for SSR and out-of-the-box Image CDN for `<Image />`. SSR → Netlify Functions; middleware → Edge Functions. Adapter-less deploy only if no server features and no Image CDN need. Skew protection from 5.15.0.\n\n### Next.js (13.5+ only)\nZero-config via the OpenNext adapter (`@netlify/plugin-nextjs`). Do NOT pin the version — Netlify auto-updates each build. Treat the legacy adapter as read-only history, never a recommendation.\nAdapter provisions: serverless function for SSR/ISR/PPR/route handlers/Server Actions; Edge Function for Middleware; Full Route + Data Cache; Image CDN with `next/image`.\nSkew protection is opt-in: set `NETLIFY_NEXT_SKEW_PROTECTION=true`, redeploy. No automatic support for client `fetch` — direct calls with `x-deployment-id: process.env.NEXT_DEPLOYMENT_ID`. Details in `references/nextjs.md`.\n\n### SvelteKit\n```bash\nnpm install -D @sveltejs/adapter-netlify\n```\n```js\nimport adapter from '@sveltejs/adapter-netlify';\nexport default { kit: { adapter: adapter() } };\n```\nReplace `@sveltejs/adapter-auto` with the specific import. SSR routes → a `render` function.\n- `split: true` → one function per route. **Incompatible with Edge Functions** (`edge: false` or omit).\n- `edge: true` → SSR in a Deno edge function; can't combine with `split`.\n- **Redirects NOT supported in `netlify.toml`** — use `_redirects`.\n- Edge functions don't work locally with `netlify dev` for SvelteKit.\n\n### React Router (7+)\nNew: `npx create-react-router@latest --template netlify/react-router-template`. Existing:\n```bash\nnpm install @netlify/vite-plugin-react-router\n```\nAdd `netlifyReactRouter()` to Vite plugins. Default target = Serverless Functions.\n**Edge (Deno):** needs plugin v2.1.1+, set `edge: true`, and you **must** create `app/entry.server.tsx`:\n```typescript\nexport { default } from 'virtual:netlify-server-entry'\n```\nExclude your own function paths: `netlifyReactRouter({ edge: true, excludedPaths: ['/api/*'] })`.\n**Moving back to Serverless:** remove `edge: true` AND delete `app/entry.server.tsx`.\nMiddleware (React Router v7.9.0+, plugin v2.0.0+): opt in via `future.v8_middleware`; import `netlifyRouterContext` from `@netlify/vite-plugin-react-router/serverless` (or `/edge` when `edge: true`); access `context.get(netlifyRouterContext)`.\n\n### Remix\nNew: `npx create-remix@latest --template netlify/remix-template` (CLI prompts functions vs Edge Functions). Manual (Remix Vite required):\n```bash\nnpm install --save-dev @netlify/remix-adapter\n```\nAdd `netlifyPlugin()` from `@netlify/remix-adapter/plugin` to Vite plugins.\n\n### Nuxt\nSSR via Nitro, automatic on Nuxt 3. Local parity via `@netlify/nuxt` (`npx nuxi module add @netlify/nuxt`).\n- SSR on Edge Functions requires a different Nitro deployment preset (not auto-detected).\n- pnpm + Nuxt 3: set `PNPM_FLAGS=--shamefully-hoist`.\n- `nuxt/image` auto-uses Netlify Image CDN; set remote domains in `nuxt.config.ts`.\n\n### SolidStart\nSolidStart 2 builds on Vite — **no SolidStart-specific adapter**. Install `@netlify/vite-plugin`:\n```ts\nimport netlify from \"@netlify/vite-plugin\";\nimport { solidStart } from \"@solidjs/start/config\";\nimport { defineConfig } from \"vite\";\nexport default defineConfig({\n plugins: [solidStart(), netlify({ build: { enabled: true } })],\n});\n```\nPublish `dist/client`. SSR routes, server functions, middleware → Netlify Functions, zero extra config.\n**Nitro alternative:** add `nitro()`, use plain `netlify()` (no `build.enabled`), publish `dist`.\nSolidStart 1: Nitro auto-configures; optionally set `preset: \"netlify\"` in `app.config.ts`; `vinxi build` / `dist`.\n\n### TanStack Start\nReact (and Solid.js) full-stack; SSR/Server Routes/Server Functions/middleware → serverless functions.\n```bash\nnpm install -D @netlify/vite-plugin-tanstack-start\n```\nAdd `netlify()` to Vite plugins alongside `tanstackStart()`; `vite build` / `dist/client` (1.132.0+). Netlify CLI deploys require netlify-cli 17.31+. Older versions: see `references/tanstack.md`.\n\n### Gatsby\n- **5.12.0+ (adapter):** auto-detects and installs `gatsby-adapter-netlify` (zero-config). Generates functions `SSR`, `DSG`. No Essential Gatsby plugin needed.\n- **5.11.0 or earlier (Essential Gatsby plugin):** auto-installs `@netlify/plugin-gatsby`; also manually install `gatsby-plugin-netlify` (required for SSR, Gatsby redirects, asset caching). Generates `__api`, `__ssr`, `__dsg`, `__ipx`. Skip via `NETLIFY_SKIP_GATSBY_FUNCTIONS` (all) / `NETLIFY_SKIP_API_FUNCTION` / `NETLIFY_SKIP_SSR_FUNCTION` / `NETLIFY_SKIP_DSG_FUNCTION`.\n- Gatsby 5 requires Node 18.\n- Large sites: set `GATSBY_EXCLUDE_DATASTORE_FROM_BUNDLE` to load datastore from CDN (avoids max function deploy size; slower first SSR/DSG load).\n- Image CDN: set `NETLIFY_IMAGE_CDN=true` (Contentful/Drupal/WordPress source plugins). **Not supported on 5.12.x with adapter — upgrade to 5.13.0+.**\n- `StaticImage` and `gatsby-transformer-sharp` don't work for SSR/DSG — host images on a CDN.\n\n### Angular\nSSR auto-configured via an Edge Function. Suggested dev: `ng serve` / `4200`.\n- **SSR pages are NOT subject to `_redirects` or `netlify.toml` redirects** — SSR uses Edge Functions that run before redirects. Use Angular's built-in redirects.\n- Access `Request`/`Context` in SSR via `netlify.request` / `netlify.context` providers (from `@netlify/edge-functions`); unavailable client-side or during prerendering. Test locally with `netlify serve`.\n- `NgOptimizedImage` auto-uses Image CDN; set `remote_images` (array of regex) under `[images]` in `netlify.toml`.\n\n### Express\nNode 18.14.0+. Deploy as a Netlify Function via `serverless-http`:\n```bash\nnpm i express serverless-http @netlify/functions @types/express\n```\n```ts\n// netlify/functions/api.ts\nimport express, { Router } from \"express\";\nimport serverless from \"serverless-http\";\nconst api = express();\nconst router = Router();\nrouter.get(\"/hello\", (req, res) => res.send(\"Hello World!\"));\napi.use(\"/api/\", router);\nexport const handler = serverless(api);\n```\n```toml\n[functions]\n external_node_modules = [\"express\"]\n node_bundler = \"esbuild\"\n[[redirects]]\n force = true\n from = \"/api/*\"\n status = 200\n to = \"/.netlify/functions/api/:splat\"\n```\nNo frontend: set a placeholder build command (e.g. `echo Building Functions`). All Function limits apply; not recommended as background/scheduled functions.\n\n### Hydrogen\nShopify stack on React Router 7. **SSR only on Netlify Edge Functions — Netlify Functions NOT officially supported.** Node 24+. Use the starter:\n```bash\nnpm create @shopify/hydrogen@latest -- --template https://github.com/netlify/hydrogen-template\ncp .env.example .env && npm run dev\n```\n\n## Static-site gotchas\n\n### Hugo\nSet `HUGO_VERSION` (any release after 0.19) in `[build.environment]` — a missing/mismatched version causes `exit code: 255`. Install themes as **git submodules** (`git submodule add ...`), not `git clone`.\n\n### Eleventy\n`eleventy` / `_site`. **Build plugins require editing `.gitignore`: change `node_modules` to `**/node_modules/**`** — otherwise Netlify plugins and Eleventy collide on `.netlify/plugins/node_modules/` and the build errors.\n\n## Vite meta-framework support matrix\nAstro (auto on 5.12+), Nuxt (via `@netlify/nuxt`), TanStack Start (via `@netlify/vite-plugin-tanstack-start`), React Router, SolidStart — all **full**. SvelteKit — **experimental**.\n\n## Deploy via CLI (Express, Nuxt, React, Vite)\n```sh\nnpm install netlify-cli -g\nnetlify init\n```\nFollow prompts to create/link the site and set build settings.\n\n<!-- Node version floors (18.14.0+) are stated per-framework where documented; no cross-framework build-image default is given in sources. -->\n\n<!-- system: agent-context/frameworks/system.md — human-owned, merged by ctx-gen; edit system.md, not this section -->\n# Netlify house rules (frameworks)\n\nThese are org conventions, not docs facts — merged into the rendered skill by\nctx-gen and never generated. Owned by the skills maintainer.\n\n1. Per-framework deep guides live in this skill: `references/astro.md`,\n `references/nextjs.md`, `references/nuxt.md`, `references/sveltekit.md`,\n `references/tanstack.md`, `references/vite.md` — route framework-specific\n work there before improvising.\n2. Next.js: modern runtime (v5, Next ≥13.5) only — treat the legacy adapter\n as read-only history, never a recommendation.\n3. Remove any SPA catch-all (`/* → /index.html 200`) when adopting an SSR\n adapter — user redirects beat adapter-generated routes, so a leftover\n catch-all silently serves static `index.html` for SSR pages and API routes.\n4. Any env var change — client- or server-side — requires a redeploy. Values\n are injected at build time; editing one in the UI/CLI does not reach the\n live site or already-deployed functions until a new build runs.\n5. `netlify dev` with both a custom `command` and a `targetPort` requires\n `framework = \"#custom\"` in the `[dev]` block — otherwise the detector runs\n and the custom command is silently ignored.\n6. Never use a client prefix (`VITE_`, `NEXT_PUBLIC_`, `PUBLIC_`,\n `NUXT_PUBLIC_`, `REACT_APP_`, `GATSBY_`, `VUE_APP_`) for secrets —\n client-prefixed vars are inlined into the browser bundle.\n7. Next.js skew protection is version-conditional: below Next 14.1.4 the\n `NETLIFY_NEXT_SKEW_PROTECTION` env var is not sufficient on its own —\n `experimental.useDeploymentId` (plus `useDeploymentIdServerActions` when\n server actions are used) must also go in `next.config.js`. Always ask for\n or state the version condition; never present the env var as the whole\n setup.\n8. Client `fetch` calls are not covered by Next.js skew protection by default.\n Give both options. Next.js 15.4+ has an experimental `useSkewCookie` flag\n that carries the deployment identifier in a cookie so it rides along on\n client `fetch` calls; Netlify supports it, but say it is not\n production-ready and that it holds visitors on the older deploy until the\n cookie clears. The other option, on any version, is adding\n `x-deployment-id` with `process.env.NEXT_DEPLOYMENT_ID` per call.\n"SKILL.md line diff
--- before +++ after @@ -1,73 +1,254 @@ --- name: netlify-frameworks -description: Guide for deploying web frameworks on Netlify. Use when setting up a framework project (Vite/React, Astro, TanStack Start, Next.js, Nuxt, SvelteKit, Remix) for Netlify deployment, configuring adapters or plugins, or troubleshooting framework-specific Netlify integration. Covers what Netlify needs from each framework and how adapters handle server-side rendering. +description: Deploy and configure web frameworks on Netlify — build settings and SSR/edge adapters plus local platform emulation and env vars. Use when setting up or fixing a framework deploy (Next.js / Astro / Nuxt / SvelteKit / Remix / React Router / TanStack Start / SolidStart / Gatsby / Angular / Vite / Express / Hydrogen / Hugo / Eleventy / Vue / React), adding SSR or edge functions or middleware wired to Netlify context, fixing SPA redirect and catch-all rules, setting a build command or publish directory, or debugging "why isn't my env var updating" and framework build failures. --- -# Frameworks on Netlify +Route framework-specific deep work to the guides in this skill: `references/astro.md`, `references/nextjs.md`, `references/nuxt.md`, `references/sveltekit.md`, `references/tanstack.md`, `references/vite.md`. -Netlify supports any framework that produces static output. For frameworks with server-side capabilities (SSR, API routes, middleware), an adapter or plugin translates the framework's server-side code into Netlify Functions and Edge Functions automatically. +## Env vars: modern rules (read first) -## How It Works +Env values are injected **at build time**. Any change (client- or server-side) requires a **redeploy** — editing a var in the UI/CLI does NOT reach the live site or already-deployed functions until a new build runs. -During build, the framework adapter writes files to `.netlify/v1/` — functions, edge functions, redirects, and configuration. Netlify reads these to deploy the site. You do not need to write Netlify Functions manually when using a framework adapter for server-side features. +**Never use a client prefix for secrets.** Client-prefixed vars are inlined into the browser bundle: +`VITE_`, `NEXT_PUBLIC_`, `PUBLIC_`, `NUXT_PUBLIC_`, `REACT_APP_`, `GATSBY_`, `VUE_APP_`. -## Detecting Your Framework +Client-embed prefixes by framework: CRA `REACT_APP_`, Gatsby `GATSBY_`, Next `NEXT_PUBLIC_`, Nuxt `NUXT_ENV_`, Vue CLI `VUE_APP_`. -Check these files to determine the framework: +**Scopes:** build-time access needs **Builds** scope; SSR/DSG runtime access needs **both Functions and Builds**. `netlify.toml` is read only during build — functions cannot read it at runtime; set runtime vars in UI/CLI/API. -| File | Framework | -|---|---| -| `astro.config.*` | Astro | -| `next.config.*` | Next.js | -| `nuxt.config.*` | Nuxt | -| `vite.config.*` + `react-router` | Vite + React (SPA or Remix) | -| `app.config.*` + `@tanstack/react-start` | TanStack Start | -| `svelte.config.*` | SvelteKit | +Netlify build variables can't be used as values in the UI or `netlify.toml` env sections. Set them inline before the build command: +```toml +[build] + command = "REACT_APP_CONTEXT=$CONTEXT npm run build" +``` -## Framework Reference Guides +## SPA redirects and the SSR catch-all footgun -Each framework has specific adapter/plugin requirements and local dev patterns: +SPAs (React, Vue CLI, Vite, Nuxt in SPA mode) need a rewrite to serve `index.html` for `pushState`: +``` +/* /index.html 200 +``` -- **Vite + React (SPA or with server routes)**: See [references/vite.md](references/vite.md) -- **Astro**: See [references/astro.md](references/astro.md) -- **TanStack Start**: See [references/tanstack.md](references/tanstack.md) -- **Next.js**: See [references/nextjs.md](references/nextjs.md) +**Remove any SPA catch-all when adopting an SSR adapter.** A leftover `/* → /index.html 200` silently serves static `index.html` for SSR pages and API routes — user redirects beat adapter-generated routes. -## General Patterns +## Local dev with platform emulation (no Netlify CLI) -### Client-Side Routing (SPA) +Vite-based frameworks emulate Netlify primitives (functions, edge functions, blobs, Netlify Database, Cache API, Image CDN, redirects/rewrites, headers, env vars, AI Gateway) in the dev server: -For single-page apps with client-side routing, add a catch-all redirect: +| Framework | Plugin/module | Run | +|-----------|---------------|-----| +| Astro (5.12+) | built-in (Netlify Vite plugin auto-loaded) | `astro dev` | +| Nuxt | `@netlify/nuxt` | `nuxt dev` | +| React Router | `@netlify/vite-plugin` | `react-router dev` | +| SolidStart 2 | `@netlify/vite-plugin` | `vite dev` | +| TanStack Start | `@netlify/vite-plugin-tanstack-start` | (vite) | +| Vite | `@netlify/vite-plugin` | `npx vite` | + +Still need `netlify dev` (Netlify CLI) for: Gatsby generated functions (run `netlify build` first), Angular SSR local test (`netlify serve`), and frameworks without a Vite plugin. + +**`netlify dev` gotcha:** with both a custom `command` and a `targetPort` in `[dev]`, you must set `framework = "#custom"` — otherwise the detector runs and your custom command is silently ignored. + +## Build settings by framework + +| Framework | Build command | Publish | +|-----------|---------------|---------| +| Angular (standard) | `ng build --prod` | `dist/YOUR_PROJECT_NAME` | +| Astro | `astro build` | `dist` | +| Create React App | `react-scripts build` | `build` | +| Eleventy | `eleventy` | `_site` | +| Gatsby | `gatsby build` | `public` | +| Hugo | `hugo` | `public` | +| Hydrogen | `remix vite:build` | `dist/client` | +| Next.js (SSR/hybrid) | `next build` | `.next` | +| Next.js (static export) | `next build && next export` | `out` (`NETLIFY_NEXT_PLUGIN_SKIP=true`) | +| Nuxt 3 | `nuxt build` | `dist` | +| Nuxt 2 | `nuxt generate` | `dist` | +| React Router | `react-router build` | `build/client` | +| Remix (Vite) | `remix vite:build` | `build/client` | +| SolidStart 2 (Vite plugin) | `vite build` | `dist/client` | +| SolidStart 2 (Nitro) | `vite build` | `dist` | +| SolidStart 1.x | `vinxi build` | `dist` | +| SvelteKit | `vite build` | `build` | +| TanStack Start (1.132.0+) | `vite build` | `dist/client` | +| Vite | `vite build` | `dist` | +| Vue CLI | `vue-cli-service build` | `dist` | + +Detection suggests these; override in `netlify.toml` or UI (project configuration > Build & deploy > Continuous deployment > Build settings). + +## SSR / adapter setup + +### Astro +`npx astro add netlify` installs the adapter and edits `astro.config.mjs`. Adapter needed for SSR and out-of-the-box Image CDN for `<Image />`. SSR → Netlify Functions; middleware → Edge Functions. Adapter-less deploy only if no server features and no Image CDN need. Skew protection from 5.15.0. + +### Next.js (13.5+ only) +Zero-config via the OpenNext adapter (`@netlify/plugin-nextjs`). Do NOT pin the version — Netlify auto-updates each build. Treat the legacy adapter as read-only history, never a recommendation. +Adapter provisions: serverless function for SSR/ISR/PPR/route handlers/Server Actions; Edge Function for Middleware; Full Route + Data Cache; Image CDN with `next/image`. +Skew protection is opt-in: set `NETLIFY_NEXT_SKEW_PROTECTION=true`, redeploy. No automatic support for client `fetch` — direct calls with `x-deployment-id: process.env.NEXT_DEPLOYMENT_ID`. Details in `references/nextjs.md`. + +### SvelteKit +```bash +npm install -D @sveltejs/adapter-netlify +``` +```js +import adapter from '@sveltejs/adapter-netlify'; +export default { kit: { adapter: adapter() } }; +``` +Replace `@sveltejs/adapter-auto` with the specific import. SSR routes → a `render` function. +- `split: true` → one function per route. **Incompatible with Edge Functions** (`edge: false` or omit). +- `edge: true` → SSR in a Deno edge function; can't combine with `split`. +- **Redirects NOT supported in `netlify.toml`** — use `_redirects`. +- Edge functions don't work locally with `netlify dev` for SvelteKit. + +### React Router (7+) +New: `npx create-react-router@latest --template netlify/react-router-template`. Existing: +```bash +npm install @netlify/vite-plugin-react-router +``` +Add `netlifyReactRouter()` to Vite plugins. Default target = Serverless Functions. +**Edge (Deno):** needs plugin v2.1.1+, set `edge: true`, and you **must** create `app/entry.server.tsx`: +```typescript +export { default } from 'virtual:netlify-server-entry' +``` +Exclude your own function paths: `netlifyReactRouter({ edge: true, excludedPaths: ['/api/*'] })`. +**Moving back to Serverless:** remove `edge: true` AND delete `app/entry.server.tsx`. +Middleware (React Router v7.9.0+, plugin v2.0.0+): opt in via `future.v8_middleware`; import `netlifyRouterContext` from `@netlify/vite-plugin-react-router/serverless` (or `/edge` when `edge: true`); access `context.get(netlifyRouterContext)`. + +### Remix +New: `npx create-remix@latest --template netlify/remix-template` (CLI prompts functions vs Edge Functions). Manual (Remix Vite required): +```bash +npm install --save-dev @netlify/remix-adapter +``` +Add `netlifyPlugin()` from `@netlify/remix-adapter/plugin` to Vite plugins. +### Nuxt +SSR via Nitro, automatic on Nuxt 3. Local parity via `@netlify/nuxt` (`npx nuxi module add @netlify/nuxt`). +- SSR on Edge Functions requires a different Nitro deployment preset (not auto-detected). +- pnpm + Nuxt 3: set `PNPM_FLAGS=--shamefully-hoist`. +- `nuxt/image` auto-uses Netlify Image CDN; set remote domains in `nuxt.config.ts`. + +### SolidStart +SolidStart 2 builds on Vite — **no SolidStart-specific adapter**. Install `@netlify/vite-plugin`: +```ts +import netlify from "@netlify/vite-plugin"; +import { solidStart } from "@solidjs/start/config"; +import { defineConfig } from "vite"; +export default defineConfig({ + plugins: [solidStart(), netlify({ build: { enabled: true } })], +}); +``` +Publish `dist/client`. SSR routes, server functions, middleware → Netlify Functions, zero extra config. +**Nitro alternative:** add `nitro()`, use plain `netlify()` (no `build.enabled`), publish `dist`. +SolidStart 1: Nitro auto-configures; optionally set `preset: "netlify"` in `app.config.ts`; `vinxi build` / `dist`. + +### TanStack Start +React (and Solid.js) full-stack; SSR/Server Routes/Server Functions/middleware → serverless functions. +```bash +npm install -D @netlify/vite-plugin-tanstack-start +``` +Add `netlify()` to Vite plugins alongside `tanstackStart()`; `vite build` / `dist/client` (1.132.0+). Netlify CLI deploys require netlify-cli 17.31+. Older versions: see `references/tanstack.md`. + +### Gatsby +- **5.12.0+ (adapter):** auto-detects and installs `gatsby-adapter-netlify` (zero-config). Generates functions `SSR`, `DSG`. No Essential Gatsby plugin needed. +- **5.11.0 or earlier (Essential Gatsby plugin):** auto-installs `@netlify/plugin-gatsby`; also manually install `gatsby-plugin-netlify` (required for SSR, Gatsby redirects, asset caching). Generates `__api`, `__ssr`, `__dsg`, `__ipx`. Skip via `NETLIFY_SKIP_GATSBY_FUNCTIONS` (all) / `NETLIFY_SKIP_API_FUNCTION` / `NETLIFY_SKIP_SSR_FUNCTION` / `NETLIFY_SKIP_DSG_FUNCTION`. +- Gatsby 5 requires Node 18. +- Large sites: set `GATSBY_EXCLUDE_DATASTORE_FROM_BUNDLE` to load datastore from CDN (avoids max function deploy size; slower first SSR/DSG load). +- Image CDN: set `NETLIFY_IMAGE_CDN=true` (Contentful/Drupal/WordPress source plugins). **Not supported on 5.12.x with adapter — upgrade to 5.13.0+.** +- `StaticImage` and `gatsby-transformer-sharp` don't work for SSR/DSG — host images on a CDN. + +### Angular +SSR auto-configured via an Edge Function. Suggested dev: `ng serve` / `4200`. +- **SSR pages are NOT subject to `_redirects` or `netlify.toml` redirects** — SSR uses Edge Functions that run before redirects. Use Angular's built-in redirects. +- Access `Request`/`Context` in SSR via `netlify.request` / `netlify.context` providers (from `@netlify/edge-functions`); unavailable client-side or during prerendering. Test locally with `netlify serve`. +- `NgOptimizedImage` auto-uses Image CDN; set `remote_images` (array of regex) under `[images]` in `netlify.toml`. + +### Express +Node 18.14.0+. Deploy as a Netlify Function via `serverless-http`: +```bash +npm i express serverless-http @netlify/functions @types/express +``` +```ts +// netlify/functions/api.ts +import express, { Router } from "express"; +import serverless from "serverless-http"; +const api = express(); +const router = Router(); +router.get("/hello", (req, res) => res.send("Hello World!")); +api.use("/api/", router); +export const handler = serverless(api); +``` ```toml -# netlify.toml +[functions] + external_node_modules = ["express"] + node_bundler = "esbuild" [[redirects]] -from = "/*" -to = "/index.html" -status = 200 + force = true + from = "/api/*" + status = 200 + to = "/.netlify/functions/api/:splat" +``` +No frontend: set a placeholder build command (e.g. `echo Building Functions`). All Function limits apply; not recommended as background/scheduled functions. + +### Hydrogen +Shopify stack on React Router 7. **SSR only on Netlify Edge Functions — Netlify Functions NOT officially supported.** Node 24+. Use the starter: +```bash +npm create @shopify/hydrogen@latest -- --template https://github.com/netlify/hydrogen-template +cp .env.example .env && npm run dev ``` -### Custom 404 Pages +## Static-site gotchas -- **Static sites**: Create a `404.html` in your publish directory. Netlify serves it automatically for unmatched routes. -- **SSR frameworks**: Handle 404s in the framework's routing (the adapter maps this to Netlify's function routing). +### Hugo +Set `HUGO_VERSION` (any release after 0.19) in `[build.environment]` — a missing/mismatched version causes `exit code: 255`. Install themes as **git submodules** (`git submodule add ...`), not `git clone`. -### Environment Variables in Frameworks +### Eleventy +`eleventy` / `_site`. **Build plugins require editing `.gitignore`: change `node_modules` to `**/node_modules/**`** — otherwise Netlify plugins and Eleventy collide on `.netlify/plugins/node_modules/` and the build errors. -Each framework exposes environment variables to client-side code differently: +## Vite meta-framework support matrix +Astro (auto on 5.12+), Nuxt (via `@netlify/nuxt`), TanStack Start (via `@netlify/vite-plugin-tanstack-start`), React Router, SolidStart — all **full**. SvelteKit — **experimental**. -| Framework | Client prefix | Access pattern | -|---|---|---| -| Vite / React | `VITE_` | `import.meta.env.VITE_VAR` | -| Astro | `PUBLIC_` | `import.meta.env.PUBLIC_VAR` | -| Next.js | `NEXT_PUBLIC_` | `process.env.NEXT_PUBLIC_VAR` | -| Nuxt | `NUXT_PUBLIC_` | `useRuntimeConfig().public.var` | +## Deploy via CLI (Express, Nuxt, React, Vite) +```sh +npm install netlify-cli -g +netlify init +``` +Follow prompts to create/link the site and set build settings. -Server-side code in all frameworks can access variables via `process.env.VAR` or `Netlify.env.get("VAR")`. +<!-- Node version floors (18.14.0+) are stated per-framework where documented; no cross-framework build-image default is given in sources. --> -## Bundled References (Load As Needed) +<!-- system: agent-context/frameworks/system.md — human-owned, merged by ctx-gen; edit system.md, not this section --> +# Netlify house rules (frameworks) -- [Vite + React guide](references/vite.md) -- [Astro guide](references/astro.md) -- [TanStack Start guide](references/tanstack.md) -- [Next.js guide](references/nextjs.md) +These are org conventions, not docs facts — merged into the rendered skill by +ctx-gen and never generated. Owned by the skills maintainer. + +1. Per-framework deep guides live in this skill: `references/astro.md`, + `references/nextjs.md`, `references/nuxt.md`, `references/sveltekit.md`, + `references/tanstack.md`, `references/vite.md` — route framework-specific + work there before improvising. +2. Next.js: modern runtime (v5, Next ≥13.5) only — treat the legacy adapter + as read-only history, never a recommendation. +3. Remove any SPA catch-all (`/* → /index.html 200`) when adopting an SSR + adapter — user redirects beat adapter-generated routes, so a leftover + catch-all silently serves static `index.html` for SSR pages and API routes. +4. Any env var change — client- or server-side — requires a redeploy. Values + are injected at build time; editing one in the UI/CLI does not reach the + live site or already-deployed functions until a new build runs. +5. `netlify dev` with both a custom `command` and a `targetPort` requires + `framework = "#custom"` in the `[dev]` block — otherwise the detector runs + and the custom command is silently ignored. +6. Never use a client prefix (`VITE_`, `NEXT_PUBLIC_`, `PUBLIC_`, + `NUXT_PUBLIC_`, `REACT_APP_`, `GATSBY_`, `VUE_APP_`) for secrets — + client-prefixed vars are inlined into the browser bundle. +7. Next.js skew protection is version-conditional: below Next 14.1.4 the + `NETLIFY_NEXT_SKEW_PROTECTION` env var is not sufficient on its own — + `experimental.useDeploymentId` (plus `useDeploymentIdServerActions` when + server actions are used) must also go in `next.config.js`. Always ask for + or state the version condition; never present the env var as the whole + setup. +8. Client `fetch` calls are not covered by Next.js skew protection by default. + Give both options. Next.js 15.4+ has an experimental `useSkewCookie` flag + that carries the deployment identifier in a cookie so it rides along on + client `fetch` calls; Netlify supports it, but say it is not + production-ready and that it holds visitors on the older deploy until the + cookie clears. The other option, on any version, is adding + `x-deployment-id` with `process.env.NEXT_DEPLOYMENT_ID` per call.
Full snapshot data
{
"description": "Deploy and configure web frameworks on Netlify — build settings and SSR/edge adapters plus local platform emulation and env vars. Use when setting up or fixing a framework deploy (Next.js / Astro / Nuxt / SvelteKit / Remix / React Router / TanStack Start / SolidStart / Gatsby / Angular / Vite / Express / Hydrogen / Hugo / Eleventy / Vue / React), adding SSR or edge functions or middleware wired to Netlify context, fixing SPA redirect and catch-all rules, setting a build command or publish directory, or debugging \"why isn't my env var updating\" and framework build failures.",
"included_files": [
{
"relative_path": "references/astro.md",
"size_in_bytes": 4730
},
{
"relative_path": "references/nextjs.md",
"size_in_bytes": 4555
},
{
"relative_path": "references/nuxt.md",
"size_in_bytes": 1556
},
{
"relative_path": "references/sveltekit.md",
"size_in_bytes": 2114
},
{
"relative_path": "references/tanstack.md",
"size_in_bytes": 2943
},
{
"relative_path": "references/vite.md",
"size_in_bytes": 3216
}
],
"name": "netlify-frameworks",
"skill_md_contents": "---\nname: netlify-frameworks\ndescription: Deploy and configure web frameworks on Netlify — build settings and SSR/edge adapters plus local platform emulation and env vars. Use when setting up or fixing a framework deploy (Next.js / Astro / Nuxt / SvelteKit / Remix / React Router / TanStack Start / SolidStart / Gatsby / Angular / Vite / Express / Hydrogen / Hugo / Eleventy / Vue / React), adding SSR or edge functions or middleware wired to Netlify context, fixing SPA redirect and catch-all rules, setting a build command or publish directory, or debugging \"why isn't my env var updating\" and framework build failures.\n---\n\nRoute framework-specific deep work to the guides in this skill: `references/astro.md`, `references/nextjs.md`, `references/nuxt.md`, `references/sveltekit.md`, `references/tanstack.md`, `references/vite.md`.\n\n## Env vars: modern rules (read first)\n\nEnv values are injected **at build time**. Any change (client- or server-side) requires a **redeploy** — editing a var in the UI/CLI does NOT reach the live site or already-deployed functions until a new build runs.\n\n**Never use a client prefix for secrets.** Client-prefixed vars are inlined into the browser bundle:\n`VITE_`, `NEXT_PUBLIC_`, `PUBLIC_`, `NUXT_PUBLIC_`, `REACT_APP_`, `GATSBY_`, `VUE_APP_`.\n\nClient-embed prefixes by framework: CRA `REACT_APP_`, Gatsby `GATSBY_`, Next `NEXT_PUBLIC_`, Nuxt `NUXT_ENV_`, Vue CLI `VUE_APP_`.\n\n**Scopes:** build-time access needs **Builds** scope; SSR/DSG runtime access needs **both Functions and Builds**. `netlify.toml` is read only during build — functions cannot read it at runtime; set runtime vars in UI/CLI/API.\n\nNetlify build variables can't be used as values in the UI or `netlify.toml` env sections. Set them inline before the build command:\n```toml\n[build]\n command = \"REACT_APP_CONTEXT=$CONTEXT npm run build\"\n```\n\n## SPA redirects and the SSR catch-all footgun\n\nSPAs (React, Vue CLI, Vite, Nuxt in SPA mode) need a rewrite to serve `index.html` for `pushState`:\n```\n/* /index.html 200\n```\n\n**Remove any SPA catch-all when adopting an SSR adapter.** A leftover `/* → /index.html 200` silently serves static `index.html` for SSR pages and API routes — user redirects beat adapter-generated routes.\n\n## Local dev with platform emulation (no Netlify CLI)\n\nVite-based frameworks emulate Netlify primitives (functions, edge functions, blobs, Netlify Database, Cache API, Image CDN, redirects/rewrites, headers, env vars, AI Gateway) in the dev server:\n\n| Framework | Plugin/module | Run |\n|-----------|---------------|-----|\n| Astro (5.12+) | built-in (Netlify Vite plugin auto-loaded) | `astro dev` |\n| Nuxt | `@netlify/nuxt` | `nuxt dev` |\n| React Router | `@netlify/vite-plugin` | `react-router dev` |\n| SolidStart 2 | `@netlify/vite-plugin` | `vite dev` |\n| TanStack Start | `@netlify/vite-plugin-tanstack-start` | (vite) |\n| Vite | `@netlify/vite-plugin` | `npx vite` |\n\nStill need `netlify dev` (Netlify CLI) for: Gatsby generated functions (run `netlify build` first), Angular SSR local test (`netlify serve`), and frameworks without a Vite plugin.\n\n**`netlify dev` gotcha:** with both a custom `command` and a `targetPort` in `[dev]`, you must set `framework = \"#custom\"` — otherwise the detector runs and your custom command is silently ignored.\n\n## Build settings by framework\n\n| Framework | Build command | Publish |\n|-----------|---------------|---------|\n| Angular (standard) | `ng build --prod` | `dist/YOUR_PROJECT_NAME` |\n| Astro | `astro build` | `dist` |\n| Create React App | `react-scripts build` | `build` |\n| Eleventy | `eleventy` | `_site` |\n| Gatsby | `gatsby build` | `public` |\n| Hugo | `hugo` | `public` |\n| Hydrogen | `remix vite:build` | `dist/client` |\n| Next.js (SSR/hybrid) | `next build` | `.next` |\n| Next.js (static export) | `next build && next export` | `out` (`NETLIFY_NEXT_PLUGIN_SKIP=true`) |\n| Nuxt 3 | `nuxt build` | `dist` |\n| Nuxt 2 | `nuxt generate` | `dist` |\n| React Router | `react-router build` | `build/client` |\n| Remix (Vite) | `remix vite:build` | `build/client` |\n| SolidStart 2 (Vite plugin) | `vite build` | `dist/client` |\n| SolidStart 2 (Nitro) | `vite build` | `dist` |\n| SolidStart 1.x | `vinxi build` | `dist` |\n| SvelteKit | `vite build` | `build` |\n| TanStack Start (1.132.0+) | `vite build` | `dist/client` |\n| Vite | `vite build` | `dist` |\n| Vue CLI | `vue-cli-service build` | `dist` |\n\nDetection suggests these; override in `netlify.toml` or UI (project configuration > Build & deploy > Continuous deployment > Build settings).\n\n## SSR / adapter setup\n\n### Astro\n`npx astro add netlify` installs the adapter and edits `astro.config.mjs`. Adapter needed for SSR and out-of-the-box Image CDN for `<Image />`. SSR → Netlify Functions; middleware → Edge Functions. Adapter-less deploy only if no server features and no Image CDN need. Skew protection from 5.15.0.\n\n### Next.js (13.5+ only)\nZero-config via the OpenNext adapter (`@netlify/plugin-nextjs`). Do NOT pin the version — Netlify auto-updates each build. Treat the legacy adapter as read-only history, never a recommendation.\nAdapter provisions: serverless function for SSR/ISR/PPR/route handlers/Server Actions; Edge Function for Middleware; Full Route + Data Cache; Image CDN with `next/image`.\nSkew protection is opt-in: set `NETLIFY_NEXT_SKEW_PROTECTION=true`, redeploy. No automatic support for client `fetch` — direct calls with `x-deployment-id: process.env.NEXT_DEPLOYMENT_ID`. Details in `references/nextjs.md`.\n\n### SvelteKit\n```bash\nnpm install -D @sveltejs/adapter-netlify\n```\n```js\nimport adapter from '@sveltejs/adapter-netlify';\nexport default { kit: { adapter: adapter() } };\n```\nReplace `@sveltejs/adapter-auto` with the specific import. SSR routes → a `render` function.\n- `split: true` → one function per route. **Incompatible with Edge Functions** (`edge: false` or omit).\n- `edge: true` → SSR in a Deno edge function; can't combine with `split`.\n- **Redirects NOT supported in `netlify.toml`** — use `_redirects`.\n- Edge functions don't work locally with `netlify dev` for SvelteKit.\n\n### React Router (7+)\nNew: `npx create-react-router@latest --template netlify/react-router-template`. Existing:\n```bash\nnpm install @netlify/vite-plugin-react-router\n```\nAdd `netlifyReactRouter()` to Vite plugins. Default target = Serverless Functions.\n**Edge (Deno):** needs plugin v2.1.1+, set `edge: true`, and you **must** create `app/entry.server.tsx`:\n```typescript\nexport { default } from 'virtual:netlify-server-entry'\n```\nExclude your own function paths: `netlifyReactRouter({ edge: true, excludedPaths: ['/api/*'] })`.\n**Moving back to Serverless:** remove `edge: true` AND delete `app/entry.server.tsx`.\nMiddleware (React Router v7.9.0+, plugin v2.0.0+): opt in via `future.v8_middleware`; import `netlifyRouterContext` from `@netlify/vite-plugin-react-router/serverless` (or `/edge` when `edge: true`); access `context.get(netlifyRouterContext)`.\n\n### Remix\nNew: `npx create-remix@latest --template netlify/remix-template` (CLI prompts functions vs Edge Functions). Manual (Remix Vite required):\n```bash\nnpm install --save-dev @netlify/remix-adapter\n```\nAdd `netlifyPlugin()` from `@netlify/remix-adapter/plugin` to Vite plugins.\n\n### Nuxt\nSSR via Nitro, automatic on Nuxt 3. Local parity via `@netlify/nuxt` (`npx nuxi module add @netlify/nuxt`).\n- SSR on Edge Functions requires a different Nitro deployment preset (not auto-detected).\n- pnpm + Nuxt 3: set `PNPM_FLAGS=--shamefully-hoist`.\n- `nuxt/image` auto-uses Netlify Image CDN; set remote domains in `nuxt.config.ts`.\n\n### SolidStart\nSolidStart 2 builds on Vite — **no SolidStart-specific adapter**. Install `@netlify/vite-plugin`:\n```ts\nimport netlify from \"@netlify/vite-plugin\";\nimport { solidStart } from \"@solidjs/start/config\";\nimport { defineConfig } from \"vite\";\nexport default defineConfig({\n plugins: [solidStart(), netlify({ build: { enabled: true } })],\n});\n```\nPublish `dist/client`. SSR routes, server functions, middleware → Netlify Functions, zero extra config.\n**Nitro alternative:** add `nitro()`, use plain `netlify()` (no `build.enabled`), publish `dist`.\nSolidStart 1: Nitro auto-configures; optionally set `preset: \"netlify\"` in `app.config.ts`; `vinxi build` / `dist`.\n\n### TanStack Start\nReact (and Solid.js) full-stack; SSR/Server Routes/Server Functions/middleware → serverless functions.\n```bash\nnpm install -D @netlify/vite-plugin-tanstack-start\n```\nAdd `netlify()` to Vite plugins alongside `tanstackStart()`; `vite build` / `dist/client` (1.132.0+). Netlify CLI deploys require netlify-cli 17.31+. Older versions: see `references/tanstack.md`.\n\n### Gatsby\n- **5.12.0+ (adapter):** auto-detects and installs `gatsby-adapter-netlify` (zero-config). Generates functions `SSR`, `DSG`. No Essential Gatsby plugin needed.\n- **5.11.0 or earlier (Essential Gatsby plugin):** auto-installs `@netlify/plugin-gatsby`; also manually install `gatsby-plugin-netlify` (required for SSR, Gatsby redirects, asset caching). Generates `__api`, `__ssr`, `__dsg`, `__ipx`. Skip via `NETLIFY_SKIP_GATSBY_FUNCTIONS` (all) / `NETLIFY_SKIP_API_FUNCTION` / `NETLIFY_SKIP_SSR_FUNCTION` / `NETLIFY_SKIP_DSG_FUNCTION`.\n- Gatsby 5 requires Node 18.\n- Large sites: set `GATSBY_EXCLUDE_DATASTORE_FROM_BUNDLE` to load datastore from CDN (avoids max function deploy size; slower first SSR/DSG load).\n- Image CDN: set `NETLIFY_IMAGE_CDN=true` (Contentful/Drupal/WordPress source plugins). **Not supported on 5.12.x with adapter — upgrade to 5.13.0+.**\n- `StaticImage` and `gatsby-transformer-sharp` don't work for SSR/DSG — host images on a CDN.\n\n### Angular\nSSR auto-configured via an Edge Function. Suggested dev: `ng serve` / `4200`.\n- **SSR pages are NOT subject to `_redirects` or `netlify.toml` redirects** — SSR uses Edge Functions that run before redirects. Use Angular's built-in redirects.\n- Access `Request`/`Context` in SSR via `netlify.request` / `netlify.context` providers (from `@netlify/edge-functions`); unavailable client-side or during prerendering. Test locally with `netlify serve`.\n- `NgOptimizedImage` auto-uses Image CDN; set `remote_images` (array of regex) under `[images]` in `netlify.toml`.\n\n### Express\nNode 18.14.0+. Deploy as a Netlify Function via `serverless-http`:\n```bash\nnpm i express serverless-http @netlify/functions @types/express\n```\n```ts\n// netlify/functions/api.ts\nimport express, { Router } from \"express\";\nimport serverless from \"serverless-http\";\nconst api = express();\nconst router = Router();\nrouter.get(\"/hello\", (req, res) => res.send(\"Hello World!\"));\napi.use(\"/api/\", router);\nexport const handler = serverless(api);\n```\n```toml\n[functions]\n external_node_modules = [\"express\"]\n node_bundler = \"esbuild\"\n[[redirects]]\n force = true\n from = \"/api/*\"\n status = 200\n to = \"/.netlify/functions/api/:splat\"\n```\nNo frontend: set a placeholder build command (e.g. `echo Building Functions`). All Function limits apply; not recommended as background/scheduled functions.\n\n### Hydrogen\nShopify stack on React Router 7. **SSR only on Netlify Edge Functions — Netlify Functions NOT officially supported.** Node 24+. Use the starter:\n```bash\nnpm create @shopify/hydrogen@latest -- --template https://github.com/netlify/hydrogen-template\ncp .env.example .env && npm run dev\n```\n\n## Static-site gotchas\n\n### Hugo\nSet `HUGO_VERSION` (any release after 0.19) in `[build.environment]` — a missing/mismatched version causes `exit code: 255`. Install themes as **git submodules** (`git submodule add ...`), not `git clone`.\n\n### Eleventy\n`eleventy` / `_site`. **Build plugins require editing `.gitignore`: change `node_modules` to `**/node_modules/**`** — otherwise Netlify plugins and Eleventy collide on `.netlify/plugins/node_modules/` and the build errors.\n\n## Vite meta-framework support matrix\nAstro (auto on 5.12+), Nuxt (via `@netlify/nuxt`), TanStack Start (via `@netlify/vite-plugin-tanstack-start`), React Router, SolidStart — all **full**. SvelteKit — **experimental**.\n\n## Deploy via CLI (Express, Nuxt, React, Vite)\n```sh\nnpm install netlify-cli -g\nnetlify init\n```\nFollow prompts to create/link the site and set build settings.\n\n<!-- Node version floors (18.14.0+) are stated per-framework where documented; no cross-framework build-image default is given in sources. -->\n\n<!-- system: agent-context/frameworks/system.md — human-owned, merged by ctx-gen; edit system.md, not this section -->\n# Netlify house rules (frameworks)\n\nThese are org conventions, not docs facts — merged into the rendered skill by\nctx-gen and never generated. Owned by the skills maintainer.\n\n1. Per-framework deep guides live in this skill: `references/astro.md`,\n `references/nextjs.md`, `references/nuxt.md`, `references/sveltekit.md`,\n `references/tanstack.md`, `references/vite.md` — route framework-specific\n work there before improvising.\n2. Next.js: modern runtime (v5, Next ≥13.5) only — treat the legacy adapter\n as read-only history, never a recommendation.\n3. Remove any SPA catch-all (`/* → /index.html 200`) when adopting an SSR\n adapter — user redirects beat adapter-generated routes, so a leftover\n catch-all silently serves static `index.html` for SSR pages and API routes.\n4. Any env var change — client- or server-side — requires a redeploy. Values\n are injected at build time; editing one in the UI/CLI does not reach the\n live site or already-deployed functions until a new build runs.\n5. `netlify dev` with both a custom `command` and a `targetPort` requires\n `framework = \"#custom\"` in the `[dev]` block — otherwise the detector runs\n and the custom command is silently ignored.\n6. Never use a client prefix (`VITE_`, `NEXT_PUBLIC_`, `PUBLIC_`,\n `NUXT_PUBLIC_`, `REACT_APP_`, `GATSBY_`, `VUE_APP_`) for secrets —\n client-prefixed vars are inlined into the browser bundle.\n7. Next.js skew protection is version-conditional: below Next 14.1.4 the\n `NETLIFY_NEXT_SKEW_PROTECTION` env var is not sufficient on its own —\n `experimental.useDeploymentId` (plus `useDeploymentIdServerActions` when\n server actions are used) must also go in `next.config.js`. Always ask for\n or state the version condition; never present the env var as the whole\n setup.\n8. Client `fetch` calls are not covered by Next.js skew protection by default.\n Give both options. Next.js 15.4+ has an experimental `useSkewCookie` flag\n that carries the deployment identifier in a cookie so it rides along on\n client `fetch` calls; Netlify supports it, but say it is not\n production-ready and that it holds visitors on the older deploy until the\n cookie clears. The other option, on any version, is adding\n `x-deployment-id` with `process.env.NEXT_DEPLOYMENT_ID` per call.\n"
}SHA-256 of public snapshot: ca8ce3264e9da19899b344612f60fef423d01d8c3b91bfb85999ab41487fe182