
netlify-config
Configure Netlify builds and routing via netlify.toml, redirects, and headers. Use when setting a build command or publish directory, adding redirects or rewrites or proxies, adding an SPA fallback rewrite, setting custom response headers or basic auth, managing environment variables and secrets, scoping vars per deploy context, marking a var as secret, disabling secret scanning, configuring functions bundling, ignoring builds, or wiring up a monorepo or JavaScript SPA on Netlify.
- Installs
- 3.3K
- Last 24h
- +29
- Trending rank
- #4451
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/netlify/context-and-tools --skill netlify-config- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads netlify-config automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Netlify configuration
Config lives in three files at the repo root (or the base/package directory for monorepos):
netlify.toml— build, contexts, plugins, functions, redirects, headers, dev._redirects— plain-text redirect/rewrite rules, saved to the publish directory, no extension._headers— plain-text response headers, saved to the publish directory.
netlify.toml values take precedence over the Netlify UI when they conflict. Paths in netlify.toml are absolute relative to the base directory (root / by default).
Modern vs legacy syntax to reach for
- Functions bundler: use
node_bundler = "esbuild".zisiis the legacy JS default; TypeScript always usesesbuild. - Temporary redirect: use
status = 302.307is unsupported. - Gatsby Image CDN: use
NETLIFY_IMAGE_CDN, not the deprecatedGATSBY_CLOUD_IMAGE_CDN. - Injecting env values into TOML:
key = "$VAR"is NOT supported (exceptsignedin proxy redirects). Use a build-commandsedsubstitution or a build plugin (see below).
netlify.toml build + contexts
[build]
base = "frontend"
publish = "dist"
command = "npm run build"
environment = { NODE_VERSION = "18" }
[context.production]
publish = "output/"
command = "make publish"
[context.deploy-preview]
publish = "dist/"
[context."feat/branch"] # quote names with special characters
command = "npm run preview"
[build] runs in Bash. Context-aware keys include [build] and [[plugins]] — but NOT [[redirects]] or [[headers]] (those are always global). Precedence, least→most specific: UI < toml < any-context property < [context.<name>] < [context.branchname].
Redirects and rewrites
_redirects rules are processed first, then netlify.toml; within each, the first matching rule top-to-bottom wins — list specific rules before general ones. Edge functions run before redirects.
SPA history-pushState fallback (required for clean URLs):
/* /index.html 200
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
_redirects syntax — from to [status] [conditions], # comments, paths case-sensitive, URL-encode special chars:
/home / 301
/my-redirect / 302
/ecommerce /store-closed 404 # custom 404 for a path
/pass-through /index.html 200 # rewrite
/best-pets/dogs /best-pets/cats.html 200! # force/shadow (! or force=true)
/news/* /blog/:splat # splat
/news/:month/:date/:year/:slug /blog/:year/:month/:date/:slug # placeholders
/store id=:id /blog/:id 301 # query params
/ /anz 302 Country=au,nz # no spaces in value list
/israel/* /israel/he/:splat 302 Language=he
/* /legacy/:splat 200 Cookie=is_legacy,my_other_cookie
[[redirects]] keywords: from, to, status (default 301), force (default false; !/shadow), query (query = {path = ":path"}), conditions ({Language, Country, Role, Cookie}), headers (proxy request headers), signed (env var name for signed proxies).
Gotchas:
- You cannot add/remove a trailing slash with a redirect — CDN normalizes URLs first; a
/x/ → /x 301!rule loops infinitely. Rely on Pretty URLs (default on). - Splat asterisks work only at the end of a segment (
/jobs/*), not mid-path (/jobs/*.htmlinvalid). Placeholders (:x) only at the start of a segment; can't mix wildcard+placeholder in one segment. - You can't exclude a path from a splat; put a more specific rule first.
Country= ISO 3166-1 alpha-2; language redirects match only the firstAccept-Languageentry.- Role-based redirects with external auth providers are Enterprise-only.
- 10,000+ redirects: use wildcards/placeholders or Edge Functions — oversized serialized output fails the deploy.
Proxies
/api/* https://api.example.com/:splat 200
/netlify-site/* https://my-other-site.netlify.app/:splat 200 # use .netlify.app, not custom domain
[[redirects]] # custom request headers + force
from = "/search"
to = "https://api.mysearch.com"
status = 200
force = true
headers = {X-From = "Netlify"}
Signed proxy (signed names an env var scoped to Runtime; must live in netlify.toml; JWS is external-only, not Netlify→Netlify):
[[redirects]]
from = "/search"
to = "https://api.mysearch.com"
status = 200
force = true
signed = "API_SIGNATURE_TOKEN_PLACEHOLDER"
Gotchas: cross-team rewrites disallowed; same-password-site rewrites OK but not across separate protected sites; proxy timeout 26 s; one hop by default; relative-path assets break (use absolute or <base>); loops silently ignored.
Custom headers
/*
X-Frame-Options: DENY
/templates/index2.html
X-Frame-Options: SAMEORIGIN
Multi-value — repeat the key (_headers) or a multiline TOML string:
[[headers]]
for = "/*"
[headers.values]
cache-control = '''
max-age=0,
no-cache,
no-store,
must-revalidate'''
Gotchas:
- Headers in
_headers/netlify.tomlare global — NOT scoped to branch/context. Workaround: strip global headers, keep header files in a custom dir, andcpthem into the publish dir from a per-context build command:[context.staging] command = "npm run build && cp ./custom-headers/_stagingHeaders ./dist/_headers" - Headers apply only to files from Netlify's store — NOT to proxied content or function/edge (SSR) responses; those must set their own headers.
- Ignored (server-set) names include
Content-Length,Content-Encoding,Location(use redirects),Set-Cookie,Server, etc. - Basic auth headers: Pro/Enterprise only. Cross-subdomain cookies need a custom domain (
netlify.appis on the Public Suffix List).
Functions
[functions]
directory = "myfunctions/" # default: <base>/netlify/functions
node_bundler = "esbuild"
external_node_modules = ["package-1"] # esbuild only; native add-ons etc.
included_files = ["files/*.md"] # ! prefix excludes
[functions."api_*"] # glob/named blocks concatenate with top-level
external_node_modules = ["package-2"]
included_files = ["!files/post-1.md"]
Environment variables
Two storage methods:
- UI / CLI / API — stored on Netlify (not the repo). Supports site + shared vars, per-context values, scopes; reaches builds, functions/edge/ODB, snippet injection, forms, signed proxies. Recommended for anything sensitive.
netlify.toml— stored in the repo. Site vars only, per-context values, no scope selection (everything gets Builds + Post processing), reaches builds + snippet injection only.
netlify.toml env vars override same-key UI/CLI/API vars.
Per-context values in TOML:
[context.production]
environment = { NODE_VERSION = "14.15.3" }
[context.deploy-preview.environment]
NOT_PRIVATE_ITEM = "not so secret"
[context.branch-deploy.environment]
NODE_ENV = "development"
CLI:
netlify env:set KEY value # --secret marks it a secret
netlify env:import .env # site vars; --replace-existing wipes others first
netlify env:unset KEY
netlify env:list --plain --context production > .env
netlify build # local build with Netlify's env vars
API: createEnvVars / updateEnvVar (is_secret: true) / setEnvVarValue / deleteEnvVar / deleteEnvVarValue.
Access syntax: Bash $VAR in build.command/ignore.command; process.env.VAR in Node scripts and plugins.
Scopes (Pro/Enterprise; default all): Builds (site builds) · Functions (Functions/Edge/ODB) · Runtime (forms, signed proxies) · Post processing (snippet injection). Shared vars are Pro/Enterprise and Team-Owner-only to read/edit. Precedence for a site+shared key collision resolves per scope — a site var only wins within the scopes it actually carries.
Naming/limits: keys alphanumeric + underscore, must start with a letter (1KEY, _KEY1 invalid); keys ≤255 chars, values ≤5,000 chars. Read-only variable names are reserved. Changes need a build + deploy.
Set the build language via reserved config vars — NODE_VERSION, NPM_FLAGS, YARN_VERSION, BUN_VERSION, RUBY_VERSION, PHP_VERSION, PYTHON_VERSION, GO_VERSION, HUGO_VERSION, PNPM_FLAGS, NPM_TOKEN (Yarn: YARN_NPM_AUTH_TOKEN), etc.
Must be set in UI/CLI/API, NOT netlify.toml (read after the repo is cloned or a runtime-only var): AWS_LAMBDA_JS_RUNTIME, GIT_LFS_ENABLED, GIT_LFS_FETCH_INCLUDE, NETLIFY_BUILD_DEBUG.
CI gotcha: defaults to true; if it breaks a build, prepend CI='' to the build command.
Injecting env values into headers/redirects
key = "$VAR" is unsupported. Only path (scope must include Builds):
[build]
command = "sed -i \"s|HEADER_PLACEHOLDER|${PROD_API_LOCATION}|g\" netlify.toml && yarn build"
sed substitution works only for [[headers]]/[[redirects]] (read after the build) and is not visible to build plugins (they run before the build command). For plugin-visible changes, use a local build plugin editing netlifyConfig.
Useful read-only build vars
CONTEXT (production/deploy-preview/branch-deploy/dev), BRANCH, COMMIT_REF, CACHED_COMMIT_REF, PULL_REQUEST, REVIEW_ID, URL, DEPLOY_URL, DEPLOY_PRIME_URL, SITE_ID, SITE_NAME.
Secrets Controller
Flag a var as secret: Contains secret values (UI) / --secret (CLI) / is_secret: true (API). Enforced, non-customizable policy:
- Secret values are write-only — no readable version after set; the flag can't be removed to reveal it.
- Secrets need explicit contexts + scopes; cannot carry the
post processingscope. - Only code on Netlify (edge/serverless/build) reads unmasked values; off-Netlify sees masked. The
dev-context value is exempt (unmasked from UI/CLI/API);netlify buildnever emits raw values.
Secret scanning runs automatically once any var is secret (and via smart detection). Fails the build on detection and logs the location. Configure via env vars set per context:
SECRETS_SCAN_ENABLED=false— disables all scanning (loses all secret protection).SECRETS_SCAN_SMART_DETECTION_ENABLED=false— disables smart detection only.SECRETS_SCAN_OMIT_KEYS,SECRETS_SCAN_OMIT_PATHS(comma lists; paths from repo root, globs OK).SECRETS_SCAN_SMART_DETECTION_OMIT_VALUES— safelist false positives (prefer this over disabling). Smart detection is Personal/Pro/Enterprise.
Scanning covers all build files, values >4 chars and non-boolean, searching plaintext + base64 + URI-encoded permutations.
Sensitive variable policy (public repos only)
Governs whether untrusted deploys (unrecognized authors) get sensitive vars. Site members' Git deploys are always trusted, even from forks. Set at Project configuration > Environment variables > Site policies:
- Require approval (default) — untrusted deploys wait for a member's approval.
- Deploy without sensitive variables — builds run, sensitive vars withheld.
- Deploy without restrictions — all vars present.
NOT available for GitHub Enterprise Server / GitLab self-managed repos (treated as private).
Ignore builds
ignore under [build] decides whether to rebuild — runs from the base directory in Bash (or Node.js 18, fixed; site package.json deps not available). Exit 1 = changed → build continues; exit 0 = no change → build stops. A build hook always builds regardless of exit code.
[build]
ignore = "git diff --quiet $CACHED_COMMIT_REF $COMMIT_REF packages/blog-1 packages/common"
[build]
ignore = "node ignore_build.js" # separate file paths must start with ./
// ignore_build.js
process.exitCode = process.env.BRANCH.includes("debug") ? 0 : 1
Monorepos
Set the site subdirectory as the package directory (keep its netlify.toml there), leave base at root /, declare deps at the subdirectory level. Package directory is UI-only — cannot be set in netlify.toml (Project configuration > Developer settings > Continuous deployment > Build settings). Config file discovery order: package dir → base dir → root. Paths in netlify.toml stay absolute relative to the base directory. netlify <cmd> --filter <site> selects a site.
JavaScript SPAs
Build command npm run <script> / yarn <script>; publish dir often dist (framework-dependent). Add the /* /index.html 200 fallback (above) for pushState routing. Code splitting + hashed filenames with atomic deploys can throw Uncaught SyntaxError: Unexpected token on stale references — disable hashed filenames, use permalinks, or a service worker.
Netlify Dev [dev]
Does NOT run in Bash (no Bash syntax in command). There is no environment key — set local env vars under [context.dev.environment].
[dev]
command = "yarn start"
targetPort = 3000 # if both command + targetPort set, framework must be "#custom"
port = 8888
framework = "#custom"
[dev.https]
certFile = "cert.pem"
keyFile = "key.pem"
Plugins & extensions
[[plugins]]
package = "netlify-plugin-check-output-for-puppy-references"
[plugins.inputs]
breeds = ["pomeranian", "chihuahua"]
[[integrations]] # build-time extension; install on team first
name = "abc-performance-extension"
[integrations.config]
output_path = "reports/performance-reports.html"
Full reference pages: build environment variables at https://docs.netlify.com/build/configure-builds/environment-variables.md, env-var overview at https://docs.netlify.com/build/environment-variables/overview.md, Secrets Controller at https://docs.netlify.com/build/environment-variables/secrets-controller.md, redirects at https://docs.netlify.com/manage/routing/redirects/overview.md, redirect options at https://docs.netlify.com/manage/routing/redirects/redirect-options.md, rewrites/proxies at https://docs.netlify.com/manage/routing/redirects/rewrites-proxies.md, custom headers at https://docs.netlify.com/manage/routing/headers.md, and file-based config at https://docs.netlify.com/build/configure-builds/file-based-configuration.md.
<!-- Plan gating for the sensitive variable policy itself is unspecified in the sources; only its public-repo requirement and the smart-detection plan list are documented. --> <!-- system: agent-context/config/system.md — human-owned, merged by ctx-gen; edit system.md, not this section -->Netlify house rules (config)
These are org conventions, not docs facts — merged into the rendered skill by ctx-gen and never generated. Owned by the skills maintainer.
- Env vars set in
netlify.tomlare NOT available to functions or edge functions at runtime — reading them there returnsundefined. Set runtime vars in the UI or withnetlify env:set, notnetlify.toml. - Never put secrets in client-prefixed env vars (
VITE_,NEXT_PUBLIC_,PUBLIC_, ...) — they are inlined into the client bundle;--secretdoes not protect them. - When snapshotting env vars locally (
netlify env:list --plain > .env), keep.envgitignored — never commit it. - State env-var scope interaction explicitly: a site variable scoped to Builds does not shadow the shared variable for other scopes — precedence resolves independently per scope (site beats shared only within the scopes the site variable actually carries).
FAQ
What does the netlify-config skill do?
Configure Netlify builds and routing via netlify.toml, redirects, and headers. Use when setting a build command or publish directory, adding redirects or rewrites or proxies, adding an SPA fallback rewrite, setting custom response headers or basic auth, managing environment variables and secrets, scoping vars per deploy context, marking a var as secret, disabling secret scanning, configuring functions bundling, ignoring builds, or wiring up a monorepo or JavaScript SPA on Netlify.
How do I install netlify-config?
Run npx skills add https://github.com/netlify/context-and-tools --skill netlify-config in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/netlify-config/ (personal) or .claude/skills/netlify-config/ (project).
Which AI agents can use netlify-config?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is netlify-config safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains netlify-config?
It is published by netlify in netlify/context-and-tools. It has 3,316 recorded installs.
More from netlify/context-and-tools
netlify-deploy
netlify/context-and-tools
Create, configure, and manage Netlify deploys from code — reach for this when setting up Git continuous deployment, running netlify deploy or netlify deploy --prod from the CLI, writing netlify.toml deploy contexts, adding a Deploy to Netlify button, wiring build hooks, configuring Deploy Previews or branch deploys, locking or skipping deploys, fixing a failed or secrets-scanning deploy, or when someone asks to "deploy my site", "set up preview deploys", "add per-branch build config", "keep staging out of Google", or "add a deploy button to my README".
netlify-functions
netlify/context-and-tools
Write, configure, and deploy Netlify serverless functions in TypeScript, JavaScript, or Go. Use this when adding an API endpoint or backend route, adding a contact form handler, wiring auth or Identity signup/login hooks, identifying which Netlify user is calling a private or team-login-protected app, building streaming or AI-proxy responses, scheduling cron jobs, running long background jobs (batch processing/scraping), reacting to deploy or form events, setting up rate limiting or region/memory config, or reading environment variables and secrets inside a function. Covers file locations, the Request/Context/Response handler shape, path routing, config options, and local testing with netlify dev.
netlify-frameworks
netlify/context-and-tools
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.
netlify-edge-functions
netlify/context-and-tools
Write, route, cache, and debug Netlify Edge Functions, the Deno-based TypeScript or JavaScript handlers in netlify/edge-functions that run at the network edge in front of static files and serverless functions. Activate this skill whenever someone wants to add auth middleware or a login gate, redirect or rewrite visitors by country or cookie, localize or personalize a page with geolocation, run A/B testing, transform or inject HTML into a response, stream server-side rendering at the edge, or cache an edge response. Also use it when an edge function silently does nothing, runs in the wrong order, ignores its Cache-Control headers, or cannot read an environment variable.
netlify-forms
netlify/context-and-tools
Serverless form handling on Netlify-hosted sites — detects HTML forms at deploy time, stores submissions, filters spam, and sends notifications. Use when adding a contact form, lead-capture form, file-upload form, or newsletter signup to a Netlify site; wiring AJAX form submission; setting up a custom thank-you page; adding a honeypot or reCAPTCHA to a form; getting forms working in Next.js, Nuxt, SvelteKit, Astro, or Gatsby; reading form submissions via the Netlify API; setting up submission notifications or ChatGPT automations on form submission events; or debugging missing submissions and forms that silently fail to register.
netlify-caching
netlify/context-and-tools
Cache dynamic and static responses on Netlify's CDN from Functions, Edge Functions, and proxies. Use when you add caching or cache-control headers to a function response, tune cache TTL or stale-while-revalidate, set up the durable cache, vary a cache key by query/header/cookie/country/language, purge or invalidate the cache by site or cache tag, use the programmatic Cache API (caches.open/match/put) or @netlify/cache helpers (fetchWithCache/cacheHeaders/getCacheStatus), speed up an expensive API call, add ISR or on-demand revalidation, or debug why a response is or isn't cached via the Cache-Status header.
Popular devops & cloud skills
microsoft-foundry
microsoft/azure-skills
Build, deploy, evaluate, optimize, fine-tune, and manage Microsoft Foundry agents, models, and resources end to end. USE FOR: foundry, azd ai agent, azd provision/deploy, hosted agent scaffold/develop/run/deploy/troubleshoot, prompt agent create, managed harness agent create, GitHub Copilot harness agent, create agent, update agent, add tool to agent, invoke agent, agent insights, evaluate agent, batch eval, continuous eval, continuous monitoring, agent CI/CD, optimize prompt, improve prompt, optimize agent instructions, Agent Optimizer scaffold, dataset curation from traces, deploy model, model fine-tuning (SFT/DPO/RFT), Foundry project, RBAC, role assignment, permissions, quota, capacity, region, deployment failure, AI Services, create Foundry resource, knowledge index, customize deployment, onboard, availability, training-data, grader, distillation, large file upload. DO NOT USE FOR: Azure Functions, App Service, general Azure deploy (use azure-deploy), general Azure prep (use azure
azure-diagnostics
microsoft/azure-skills
Debug Azure production issues on Azure using AppLens, Azure Monitor, resource health, and safe triage. WHEN: debug production issues, troubleshoot app service, app service high CPU, app service deployment failure, troubleshoot container apps, container app 503 or target port mismatch, troubleshoot functions, function telemetry missing or stopped after a config/connection-string change, troubleshoot AKS, VM RDP, Linux SSH, VM black screen, can't connect to VM, reset VM password, NSG or firewall blocking, kubectl cannot connect, kube-system/CoreDNS failures, pod pending, crashloop, node not ready, upgrade failures, analyze logs, KQL, insights, image pull failures, cold start issues, health probe failures, resource health, root cause of errors, troubleshoot event hubs, troubleshoot service bus, messaging SDK error, AMQP connection failure, message lock lost, lock renewal during long-running processing, service bus dead letter.
azure-prepare
microsoft/azure-skills
Prepare azd-based Azure projects for deployment: generates azure.yaml, infrastructure (Bicep/Terraform), and Dockerfiles for the Azure Developer CLI (azd) workflow. USE ONLY when the user explicitly wants to use azd as the deployment tool, or the project already has an azure.yaml file. DO NOT USE FOR: non-azd deployments, Python App Service code-only deploys (use python-appservice-deploy), or cross-cloud migration (use azure-cloud-migrate). WHEN: prepare app for azd, create azure.yaml, set up azd infrastructure, modernize app for Azure with azd, deploy with azd, function app, timer trigger, service bus trigger, event-driven function, managed identity, generate Bicep, generate Terraform, create and deploy to Azure.
azure-ai
microsoft/azure-skills
Use for Azure AI: Search, Speech, OpenAI, Document Intelligence. Helps with search, vector/hybrid search, speech-to-text, text-to-speech, transcription, OCR. WHEN: AI Search, query search, vector search, hybrid search, semantic search, speech-to-text, text-to-speech, transcribe, OCR, convert text to speech.
azure-deploy
microsoft/azure-skills
Execute Azure deployments for ALREADY-PREPARED applications that have existing .azure/deployment-plan.md and infrastructure files. DO NOT use this skill when the user asks to CREATE a new application — use azure-prepare instead. This skill runs azd up, azd deploy, terraform apply, and az deployment commands with built-in error recovery. Requires .azure/deployment-plan.md from azure-prepare and validated status from azure-validate. WHEN: "run azd up", "run azd deploy", "execute deployment", "push to production", "push to cloud", "go live", "ship it", "bicep deploy", "terraform apply", "publish to Azure", "launch on Azure". DO NOT USE WHEN: "create and deploy", "build and deploy", "create a new app", "set up infrastructure", "create and deploy to Azure using Terraform" — use azure-prepare for these.
azure-validate
microsoft/azure-skills
Pre-deployment validation for Azure readiness. Run deep checks on configuration, infrastructure (Bicep or Terraform), RBAC role assignments, managed identity permissions, and prerequisites before deploying. WHEN: validate my app, check deployment readiness, run preflight checks, verify configuration, check if ready to deploy, validate azure.yaml, validate Bicep, test before deploying, troubleshoot deployment errors, validate Azure Functions, validate function app, validate serverless deployment, verify RBAC roles, check role assignments, review managed identity permissions, what-if analysis, validate Container Apps deployment.