Skip to content
Deployment
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

From plugin
netlify-skills
3715 skills1 MCP
Install
$ npx -y skills add netlify/context-and-tools --skill netlify-config --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/netlify-config

Context preview

The summary Claude sees to decide when to auto-load this skill.

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

SKILL.md

netlify-config.SKILL.md
name: netlify-config
description: 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".

Netlify configuration

`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.

Footguns (read first)

  • **Env vars in `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`.
  • **Never put secrets in client-prefixed vars** (`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.
  • **Direct env injection into `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.
  • **Proxy rewrites time out at 26 seconds.** HTTP `307` is unsupported — use `302`.

`netlify.toml` — core structure

[build]
  base = "project/"          # base directory
  publish = "build-output/"  # relative to base, default /
  command = "npm run build"  # runs in Bash shell
  [build.environment]
    NODE_VERSION = "18"

[context.production]         # production branch deploy
  command = "make publish"
  environment = { NODE_VERSION = "14.15.3" }
[context.deploy-preview]     # PR/MR previews
  publish = "dist/"
[context.branch-deploy]      # non-production branches
  command = "echo branch"
[context.dev.environment]    # local dev env vars ONLY
  NODE_ENV = "development"
[context.staging]            # a specific branch name
  command = "echo staging"
[context."feat/branch"]      # quote branches with special chars
  command = "echo special"

Context 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.

Functions config

[functions]
  directory = "functions/"           # default: YOUR_BASE_DIR/netlify/functions
  node_bundler = "esbuild"           # prefer esbuild; zisi is the JS default
  external_node_modules = ["package-1"]
  included_files = ["files/*.md", "!files/skip.md"]

[functions."api_*"]                  # glob filter; values CONCATENATE across matches
  external_node_modules = ["package-2"]
  • `esbuild` = smaller/faster artifacts; TypeScript functions **always** use `esbuild`.
  • `external_node_modules` applies only with `esbuild`. `included_files`: `*` wildcard, `!` excludes; paths absolute to base.

Environment variables

Set runtime/scoped vars via CLI/UI/API (not `netlify.toml`):

netlify env:set MY_KEY value --secret     # --secret marks an env var secret
netlify env:import .env                    # site-level, all scopes, all contexts
netlify env:list --plain --context production > .env
netlify env:unset MY_KEY

**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.

Build variables

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`), `BR

Read more
Ships withnetlify-skills

Public Netlify skills for AI coding agents. Each skill is a focused, factual reference for a Netlify platform primitive — designed to help agents build correctly on Netlify without needing to search docs.

Get the whole plugin

Other skills on netlify-skills.