netlifyDeploy :: AttrSet → Effect

Deploys content to Netlify, the CDN and web platform that coined JamStack.


effects.netlifyDeploy {
  siteId = "...";
  secretName = "default-netlify";
  productionDeployment = true;
  content = runCommand "site" {} ''
    mkdir $out
    echo "<h1>Hi!</h1>" >$out/index.html

Example secret:

  "netlify-test-account": {
    "kind": "Secret",
    "data": {
      "token": "..."
    "condition": {
      "and": [
        { "isOwner": "my-github-org" },
        { "isRepo": "my-site-repo" }

Example impure build and deploy:

effects.netlifyDeploy {

  # ...

  content = "./public"; # match netlify.toml build.base field
  extraDeployArgs = ["--build"];
  preEffect = lib.optionalString (!production) ''
    # pre-install a robots.txt to avoid indexing of non-prod
    mkdir -p public
    { echo 'User-agent: *'
      echo 'Disallow: /'
    } >public/robots.txt



An opaque identifier assigned by Netlify.

You can retrieve this value by logging in to Netlify, creating or navigating to the site you want to deploy, click Site settings, then copy the value after Site ID: from the Site information box.

Disable Netlify’s integrated builds

While you’re in the Site settings, you’ll want to make sure Netlify’s deployments don’t interfere.

Go to Build & deploy in the Site settings menu, then click Edit settings in the Build settings box. Select Stop builds and Save.

See Stop or activate builds for more details.


The secret that will be looked up in secrets.json.

The data field must contain a "token" field, with a string value that is a Netlify personal access token. To make one, navigate to Personal access tokens and use New access token.


Path to the site content, also known as the Publish directory.

This includes files such as netlify.toml, _redirects, and all web resources, like index.html, style sheets, etc.

You’ll typically put a derivation here.


Extra arguments to pass to the netlify deploy invocation.


Whether this is a production deployment. Default: false.

You can use the herculesCI attribute parameters to make this conditional on the branch name.

In a flake:

effects = { branch, ... }: {
  netlify = netlifyDeploy {
    # ...
    productionDeployment = branch == "main";

In a ci.nix, default.nix or flake:

herculesCI = { branch }: {
  onPush.default =
  # let netlifyDeploy = ...; in
    outputs = {
      effects.netlify = netlifyDeploy {
        # ...
        productionDeployment = branch == "main";