npx skills add ...
npx skills add netlify/context-and-tools --skill netlify-config
Configure Netlify projects via netlify.toml and the _headers/_redirects files — covering build settings and deploy contexts alongside environment variables/scopes and the Secrets Controller plus redirect/rewrite/proxy and custom-header rules. Use when setting a build command or publish directory, adding redirect or rewrite or proxy rules, configuring custom headers or basic auth, setting or scoping environment variables and secrets, wiring up a monorepo or SPA fallback, or skipping unnecessary builds. Reach for this whenever you touch netlify.toml or ask "why is my env var undefined in a function" or "how do I redirect this path".
npx skills add netlify/context-and-tools --skill netlify-config
netlify.toml lives at the repo root (or set base/package directory for monorepos). Settings in netlify.toml override the Netlify UI on conflict. _headers and _redirects are extensionless plain-text files in the publish directory, processed before netlify.toml rules.
netlify.toml are NOT available to functions or edge functions at runtime — reading them there returns undefined. Vars declared in netlify.toml only get the Builds and Post processing scopes. Set runtime vars in the UI or with netlify env:set.VITE_, NEXT_PUBLIC_, PUBLIC_, …) — they are inlined into the client bundle. --secret does not protect them..env is not read by the Netlify build system — import variables into Netlify first (netlify env:import). The CLI reads .env only for local builds.netlify.toml (key = "$VAR") is unsupported — except signed proxy redirects. Use a build plugin or sed in the build command.[[redirects]] and [[headers]] are global — NOT context-aware, cannot be scoped to branches/contexts. Workaround: per-context build command copies a custom file into the publish directory.307 is unsupported — use 302.netlify.toml — core structureContext precedence (least → most specific): UI settings < base context-aware key < [context.production|deploy-preview|branch-deploy|dev] < [context.branchname]. Only [build] and [[plugins]] are context-aware. All paths are absolute relative to the base directory (root / default).
Config file search order: package directory → base directory → root.
esbuild = smaller/faster artifacts; TypeScript functions always use esbuild.external_node_modules applies only with esbuild. included_files: * wildcard, ! excludes; paths absolute to base.Set runtime/scoped vars via CLI/UI/API (not netlify.toml):
Keep any .env snapshot gitignored — never commit it.
Types: site vars (one site) vs shared vars (whole team; Pro/Enterprise; Team Owners only).
Scopes (Pro/Enterprise; default = all): Builds, Functions (also Edge Functions + On-demand Builders), Runtime (forms, signed proxy redirects), Post processing (snippet injection). Vars from netlify.toml are locked to Builds + Post processing.
Scope precedence is independent per scope: a site variable scoped only to Builds does NOT shadow a shared variable for the Functions scope — the shared value still applies there. Site beats shared only within the scopes the site variable actually carries.
Deploy-context values: Production, Deploy Previews, Branch deploys (override per-branch with a Branch value, wildcard suffix release/*), Preview server, Local development.
Overrides: netlify.toml vars override same-key UI/CLI/API vars. Site var beats shared var per its scopes/contexts.
Limits: keys ≤ 255 chars, alphanumeric + underscore, first char a letter (KEY1 ok; 1KEY/_KEY1 invalid). Values ≤ 5,000 chars (functions within AWS limits). Reserved read-only names can't be overridden.
Settable in netlify.toml [build.environment]: NODE_VERSION, NODE_ENV, NPM_VERSION, NPM_FLAGS, NPM_TOKEN, YARN_VERSION, PNPM_FLAGS, BUN_VERSION, RUBY_VERSION, PHP_VERSION, PYTHON_VERSION, GO_VERSION, HUGO_VERSION, NETLIFY_USE_YARN, CI, etc.
Set in UI/CLI only (NOT netlify.toml, which is read after clone): AWS_LAMBDA_JS_RUNTIME, GIT_LFS_ENABLED, GIT_LFS_FETCH_INCLUDE, NETLIFY_BUILD_DEBUG.
Read-only build metadata (examples): NETLIFY, BUILD_ID, CONTEXT (production/deploy-preview/branch-deploy/dev), BRANCH, HEAD, COMMIT_REF, CACHED_COMMIT_REF, PULL_REQUEST, REVIEW_ID, URL, DEPLOY_URL, DEPLOY_PRIME_URL, DEPLOY_ID, SITE_NAME, SITE_ID, ACCOUNT_ID.
Access: Bash $VAR_NAME in build/ignore commands; process.env.VAR_NAME in Node scripts and plugins. Scope must include Builds.
Substitution only reaches [[headers]]/[[redirects]] (read after build); NOT available to build plugins. Alternatively mutate netlifyConfig in a local build plugin.
_redirects (one rule per line) or [[redirects]]. Rules process top-down; first match wins. _redirects/file rules run before netlify.toml.
! in _redirects or force = true in toml.*) only at the end of a path segment (/jobs/*.html won't work). Can't exclude a path from a splat — order a more specific rule first.id=:id matches URLs with only id and no other params. List optional-param variants most-general-last.Country=au,nz). Country = ISO 3166-1 alpha-2; Language = browser/locale codes, matches the FIRST Accept-Language entry. nf_country/nf_lang cookies override.307 unsupported → use 302._redirects + netlify.toml can fail the deploy if too large — consider Edge Functions.<base>..netlify.app subdomain. Rewrites into a separate password-protected site are not allowed.netlify.toml only)Must be in netlify.toml; env var scope must include Runtime; not supported proxying Netlify→Netlify. Netlify sends the JWS as HMAC HS256 in the x-nf-sign header. (This is the one place $VAR-style env injection is allowed.)
Content-Length, Content-Encoding, Location (use redirects), Set-Cookie (may be overridden), Server, Date, Age, Connection, Transfer-Encoding, etc.*.netlify.app (Public Suffix List) — needs a custom domain.Mark a var secret via --secret (CLI), is_secret: true (API), or the UI. Enforced, non-customizable policy:
post processing scope.dev context value is unmasked and exempt.SECRETS_SCAN_SMART_DETECTION_OMIT_VALUES (comma-separated), then redeploy.Sensitive variable policy (public repos only): untrusted deploys (unrecognized authors) default to Require approval; alternatives are Deploy without sensitive variables or Deploy without restrictions. Not available for GitHub Enterprise Server / GitLab self-managed (treated as private).
0 = no changes, build stops; exit 1 = changed, build continues.package.json deps unavailable. Referenced file paths must start with ./.Node.js variant:
Hashed/code-split filenames + atomic deploys can break asset refs (Uncaught SyntaxError: Unexpected token) — disable hashed filenames, use permalinks, or a service worker.
Recommended: set the site's subdirectory as the package directory (keep netlify.toml there), leave base directory at repo root /, declare deps at the subdirectory level.
netlify.toml. Base directory can be set in root-level netlify.toml ([build] base) and overrides the UI./frontend + plugin at /frontend/packages/my-app/plugins → specify /packages/my-app/plugins/....ignore command. CLI: --filter <site>. Netlify caches all node_modules regardless of where deps are declared.[dev] has no environment property — set local env vars in [context.dev.environment] instead. framework values: #auto (default), #static, #custom.
For Deploy-to-Netlify buttons use [template] / [template.environment].
Post-processing pretty URLs:
These are org conventions, not docs facts — merged into the rendered skill by ctx-gen and never generated. Owned by the skills maintainer.
netlify.toml are NOT available to functions or edge
functions at runtime — reading them there returns undefined. Set
runtime vars in the UI or with netlify env:set, not netlify.toml.VITE_, NEXT_PUBLIC_,
PUBLIC_, ...) — they are inlined into the client bundle; --secret
does not protect them.netlify env:list --plain > .env),
keep .env gitignored — never commit it.