Skip to content
Netlify Deploy

Netlify Deploy Skill

Netlify's official deploy skill: netlify.toml deploy contexts and their precedence, CLI and drag-and-drop deploys, Deploy Previews, build hooks, skew protection, and secrets-scanning build failures.

GitHub Docs

Install

Install with the skills CLI

One command for Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf and dozens of other agents. Needs Node.js; the skill is fetched straight from netlify/context-and-tools.

$ npx skills add netlify/context-and-tools --skill netlify-deploy

Run it in a terminal. The CLI finds the agents installed on your machine, asks which ones to add the skill to, and whether to install it into the folder you ran it from or for all your projects.

Other ways to install

Copy the whole skill folder — SKILL.md and any scripts or references beside it — into ~/.claude/skills/netlify-deploy/, where Claude Code picks it up in every project. Only git is needed.

tmp=$(mktemp -d) && \
  git clone --depth 1 --branch main https://github.com/netlify/context-and-tools.git "$tmp" && \
  mkdir -p ~/.claude/skills && \
  cp -R "$tmp"/skills/netlify-deploy ~/.claude/skills/netlify-deploy

No scripts or references next to it? Saving the SKILL.md alone as ~/.claude/skills/netlify-deploy/SKILL.md works too.

Using another agent? Its personal skills folder
Codex
~/.agents/skills/
Cursor
~/.cursor/skills/
GitHub Copilot
~/.copilot/skills/
Gemini CLI
~/.gemini/skills/
Windsurf
~/.codeium/windsurf/skills/
OpenCode
~/.config/opencode/skills/

About

  • Full netlify.toml deploy-context reference, including precedence between contexts
  • Warns that netlify.toml environment variables never reach the deploy environment
  • Covers CLI, Git continuous deployment, Deploy to Netlify buttons and drag-and-drop
  • Explains secrets-scanning build failures and how to clear them
  • Skew protection so clients never straddle two deploys
  • Build hooks, deploy management and rollbacks

Netlify's official agent skill is about the part of Netlify that actually goes wrong: getting a deploy out, and understanding why one failed. It covers Git continuous deployment, CLI manual and anonymous deploys, Deploy to Netlify buttons, Netlify Drop drag-and-drop, and per-context build configuration.

Deploy contexts

The core of the skill is netlify.toml context configuration — the five predefined contexts (production, deploy-preview, branch-deploy, preview-server, dev), custom branch contexts, and the precedence between them: site globals lose to context overrides, a named-branch context beats the general branch-deploy, and file-based config beats the UI. It also flags the double-bracket syntax that per-context plugin blocks require, which misbehaves quietly when written singly.

The footguns it names
  • Secrets in `netlify.toml`. The file is committed to the repository. Sensitive values belong in the UI, CLI or API — and separately, environment variables declared in netlify.toml are not available to the deploy environment (Functions, runtime, post-processing); only UI/CLI/API-created ones are.
  • Secrets-scanning failures, which fail a build outright rather than warn, and what to do about them.
  • Skew protection, so a client running old assets never talks to a newly deployed server.
Also covered

Deploy Previews and branch deploys, skipping a deploy, build hooks, managing and rolling back deploys, netlify create from a natural-language prompt, and the constraints attached to each deploy path.

Netlify splits its skills by concern: environment-variable management lives in netlify-config and local development in netlify-frameworks, so this one stays about shipping. Published in netlify/context-and-tools under the MIT licence.

Try it

Once installed, ask your agent something like:

Link this repo to my Netlify site, ship a draft deploy, then tail the edge function logs and tell me why the redirect is 500ing.

SKILL.md

The instructions your agent loads, as published by Netlify.

SKILL.md
name
netlify-deploy
description
Create and manage Netlify deploys — Git continuous deployment, CLI manual/anonymous deploys, Deploy to Netlify buttons, drag-and-drop, and per-context netlify.toml build settings. Use when linking a repo, deploying from the CLI, setting up Deploy Previews or branch deploys, configuring deploy contexts, adding skew protection, fixing a failed or secrets-flagged deploy, or wiring build hooks and Deploy to Netlify buttons.

Netlify deploy

Deploy context config (netlify.toml, current form)

Configure per-context build settings in netlify.toml at the repo root. Five predefined contexts: production, deploy-preview, branch-deploy, preview-server, dev. Branch names also work as custom contexts (a staging branch matches a staging context).

[context.production]
  command = "make production"
  [context.production.environment]
    ACCESS_TOKEN = "super secret"
  # Plugins context REQUIRES double brackets:
  [[context.production.plugins]]
    package = "@netlify/plugin-sitemap"

[context.deploy-preview.environment]
  ACCESS_TOKEN = "not so secret"

[context.branch-deploy]
  command = "make staging"

[context.dev.environment]
  NODE_ENV = "development"

# Specific-branch context (overrides branch-deploy):
[context.feature]
  command = "make feature"

[context."features/branch"]
  command = "gulp"

Precedence: site globals < context overrides; production overrides globals when building production; more specific contexts (a named branch) override general ones (branch-deploy). Only explicitly-set options are overridden. File-based config overrides UI settings.

Footgun — secrets in netlify.toml: netlify.toml is committed to your repo. Do not put sensitive env values here, especially for public repos. Set secrets via the Netlify UI/CLI/API instead. Also: env vars declared in netlify.toml are NOT available to the deploy environment (Functions/Runtime/Post-processing scopes) — only UI/CLI/API-created vars are.

CLI deploys
netlify create              # new project from a natural-language prompt
netlify deploy              # manual deploy, no continuous deployment
netlify deploy --prod       # deploy directly to production
netlify deploy --allow-anonymous   # temp deploy, claim within 1 hour
npm update -g netlify-cli   # skew protection needs CLI v23.11.0+

Manual deploys do NOT run a build command (exception: Netlify Drop builds for you when logged in). Anonymous deploys create a temporary project claimable within one hour; on claim it adopts the team's default visibility.

Footgun — link writes `.netlify/state.json`: every linking/create path writes .netlify/state.json. Add .netlify to .gitignore so it is never committed.

Footgun — manual `--prod` on a Git-connected site: the next push to the production branch silently replaces your hand-shipped deploy. Warn the user before running it; if the deploy must stay live, lock the published deploy.

Git continuous deployment

Connect a Git repo (Git provider OAuth2 or the Netlify GitHub App). Netlify runs your build command and deploys on every push. Production deploys are triggered by pushes to the production branch (default main); Deploy Previews are built for pull/merge requests and agent runs.

Deploy Previews & branch deploys
  • Deploy Previews build by default for PRs/MRs and agent runs. Base branch of a Deploy Preview must be a production branch or a branch with branch deploys enabled.
  • Branch deploys are OFF by default — a Developer/Owner must enable them: Project configuration > Build & deploy > Continuous Deployment > Branches and deploy contexts > Configure. Add individual branches, use a features/* prefix wildcard, or select All.
  • URL prefixes: branch deploys <branch>--; PR/MR previews deploy-preview-<number>--; agent previews agent-<runID>--; permalinks <deployID>--.
  • While the initial Deploy Preview builds, its URL returns Not Found.

Deploy Preview entry path — set in the PR/MR description (updates the PR comment link):

@netlify /start/choose-your-path

Push a new (or empty) commit to regenerate the link. Once set in the PR/MR, you cannot override the entry path in the Netlify Drawer.

Skip a deploy

Add [skip ci] or [skip netlify] to a PR/MR title (skips the Deploy Preview) or anywhere in a commit message (skips branch/production deploy). For a multi-commit push, put it in the most recent commit. The next commit without the token deploys all skipped changes.

Deploy to Netlify button

Template code must be in a public GitHub.com or GitLab.com repo.

[![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/netlify/netlify-statuskit)

URL parameters (query params; env vars go in the URL hash):

# require/set env vars via hash (values may be null; processed client-side, not logged)
...?repository=REPO#SECRET_TOKEN=value&CUSTOM_LOGO=
&fullConfiguration=true   # extra step to install SDK extensions + configure before deploy
&base=blog                # alternate base dir for monorepos (repo still fully cloned)
&create_from_path=examples/hello   # clone only this subdirectory
&branch=beta-feature      # set production branch to this branch

File-based template config in root netlify.toml [template] section:

[template]
  incoming-hooks = ["Contentful"]
  required-extensions = ["supabase"]
[template.environment]
  SECRET_TOKEN = "change me for your secret token"   # label only; cannot set real values

[template] cannot set env var values (use the URL hash) or a base directory (use base). With an alternate base, the netlify.toml in the base directory wins over root config for that site's builds. USAGE.md at repo root shows extra instructions during the fullConfiguration flow.

Drag and drop (Netlify Drop)

Drag a folder to https://app.netlify.com/drop. Logged in: Netlify detects the framework and builds before publishing (a pre-built output folder also works). Not logged in: files publish as-is. Update a drag-and-drop site by dropping the new output folder at the dropzone on the site's Deploys page (works for any non-Git site).

Build hooks

Build hooks give unique URLs to trigger builds/deploys. Builds from build hooks are treated as trusted and are NOT subject to the Deploy Request Policy.

Managing deploys
  • Find: Deploys tab; search by deploy ID or branch; filter by time frame, deploy context, and status.
  • Lock (pause publishing): on the Deploys list, Lock to stop auto publishing. New deploys still build but don't publish. Unlock to start auto publishing to resume. Use this to keep a specific deploy live.
  • Cancel: on the in-progress deploy's detail page, Cancel deploy.
  • Retry: builds from the branch HEAD — if HEAD moved past the original deploy SHA, it still builds from HEAD.
  • Download: deploy detail page — single file via Deploy file browser, or all files as ZIP via header Download.
  • Delete: Developer/Team Owner only. You cannot delete the currently-published deploy or one in progress. Permanent; does not reduce cost or preserve build minutes.

Netlify auto-deletes deploys older than 30 days (90 days on paid plans); failed/canceled deploys are cleaned up on the same schedule. It never auto-deletes the published deploy, the most recent successful production deploy, or the most recent successful branch deploy per branch.

Fix a failed deploy: a failed deploy never publishes — the previously published deploy stays live, so there is nothing to restore. Fix forward: use the "Why did it fail?" diagnosis above the deploy log, revert the offending commit, and let CI redeploy. Retry (optionally clearing cache) rebuilds from branch HEAD.

Skew protection

Available on all plans. Routes requests to the server version that matches each client, avoiding version skew across deploys. Requires Netlify CLI v23.11.0+ for CLI deploys.

  • Production context only. Branch deploys, Deploy Previews, and permalinks bypass skew protection and serve the latest deploy for that context.
  • Framework support: Astro 5.15.0+ (on by default via the Netlify adapter); Next.js (optional; older versions need a config change). Framework maintainers add support via netlify/v1/skew-protection.json.
  • Password protection: works only if you protect non-production deploys only. Protecting production deploys (or all deploys) disables/ignores skew protection.
  • Netlify discards skew signals on hard navigation (Sec-Fetch-Mode: navigate, or Sec-Fetch-Site present and not same-origin).
Secrets scanning failures

If a deploy fails secrets scanning and the flagged value is a real secret, that is a leak: stop shipping it in client/published output and rotate it. Never disable the scanner over a real leak. For genuine non-secrets, scope narrowly with SECRETS_SCAN_OMIT_KEYS / SECRETS_SCAN_OMIT_PATHS — never SECRETS_SCAN_ENABLED=false.

Constraints
  • 54,000 files per directory max — any directory in your publish dir over this limit fails the deploy. No limit on total files.
  • Deploys are atomic: only changed files upload; nothing goes live until the whole deploy is ready.
  • Only the published production deploy and most recent branch deploys are indexable; other previews get X-Robots-Tag: noindex.
  • Deploy Request Policy: private-repo deploys build only for recognized authors (Owners, Developers, Git Contributors; Marketplace bots count). Non-team-member deploys land as Pending approval until a Team Owner approves/matches them. Build-hook builds are exempt.
  • Retention limit is adjustable only on Enterprise (up to 365 days). Lock/unlock event notifications: Pro and Enterprise.
More

Deep guides in this skill: references/netlify-toml.md, references/cli-commands.md, references/deployment-patterns.md.

<!-- Gap: deploy-overview states failed/canceled deploys are deleted at 6 months, contradicting the 30/90-day cleanup figure used above; the 30/90-day value is stated here as the documented default. -->

<!-- system: agent-context/deploy/system.md — human-owned, merged by ctx-gen; edit system.md, not this section -->

Netlify house rules (deploy)

These are org conventions, not docs facts — merged into the rendered skill by
ctx-gen and never generated. Owned by the skills maintainer.

  1. Agents do not roll back deploys: never call restoreSiteDeploy or

publishDeploy to restore an older deploy. Fix forward — revert the
commit and let CI deploy it.

  1. A failed deploy never publishes; on failure there is nothing to roll

back.

  1. Deep guides live in this skill: references/netlify-toml.md,

references/cli-commands.md, references/deployment-patterns.md.

  1. The frontmatter description must never advertise rollback or restore as a

capability — no "roll back", "restore a deploy", or equivalent.

  1. When the user asks to roll back or restore a previous deploy, correct the

premise rather than complying: after a failed deploy the previous deploy
is still live and there is nothing to restore; for a bad published deploy,
fix forward per rule 1. Do not hand over restoreSiteDeploy /
publishDeploy or a dashboard rollback as the answer.

  1. Always add .netlify to .gitignore when linking or creating a site —

every linking path writes .netlify/state.json, which must not be
committed. Mention it whenever you link.

  1. Secrets-scanning deploy failures: if the flagged value is a real secret,

that is a leak — stop shipping it in client/published output and rotate
it; never silence the scanner over a real leak. For genuinely non-secret
values, scope narrowly with SECRETS_SCAN_OMIT_KEYS /
SECRETS_SCAN_OMIT_PATHS, never SECRETS_SCAN_ENABLED=false.

  1. Before running a manual netlify deploy --prod on a site with Git CD

connected, warn the user that the next push to the production branch
silently replaces the hand-shipped deploy; suggest locking the published
deploy if it must stay live.

Install

Vercel's official deployment skill — inspects project state, picks the right deploy path, and defaults to preview deployments with a claimable URL when no account is linked.

Featured

Railway's official agent skill: create projects, provision databases and buckets, deploy, manage variables and domains, and read build failures back — from the CLI, API or MCP server.

Browse all skills →