* feat(netlify): expose builders ttl as a local * add changeset * docs(netlify): caching using on-demand builders * reword readme section * Update packages/integrations/netlify/package.json Co-authored-by: Bjorn Lu <bjornlu.dev@gmail.com> * include builders-types.d.ts in the distribution * document caveat regarding query params * update changeset * mutation -> function * locals.netlify -> locals.runtime * update types and changeset * Apply suggestions from code review Co-authored-by: Elian ☕️ <hello@elian.codes> * Apply suggestions from code review Co-authored-by: Elian ☕️ <hello@elian.codes> --------- Co-authored-by: Bjorn Lu <bjornlu.dev@gmail.com> Co-authored-by: Elian ☕️ <hello@elian.codes>
11 KiB
@astrojs/netlify
This adapter allows Astro to deploy your SSR site to Netlify.
Learn how to deploy your Astro site in our Netlify deployment guide.
Why Astro Netlify
If you're using Astro as a static site builder—its behavior out of the box—you don't need an adapter.
If you wish to use server-side rendering (SSR), Astro requires an adapter that matches your deployment runtime.
Netlify is a deployment platform that allows you to host your site by connecting directly to your GitHub repository. This adapter enhances the Astro build process to prepare your project for deployment through Netlify.
Installation
Add the Netlify adapter to enable SSR in your Astro project with the following astro add
command. This will install the adapter and make the appropriate changes to your astro.config.mjs
file in one step.
# Using NPM
npx astro add netlify
# Using Yarn
yarn astro add netlify
# Using PNPM
pnpm astro add netlify
If you prefer to install the adapter manually instead, complete the following two steps:
-
Install the Netlify adapter to your project’s dependencies using your preferred package manager. If you’re using npm or aren’t sure, run this in the terminal:
npm install @astrojs/netlify
-
Add two new lines to your
astro.config.mjs
project configuration file.// astro.config.mjs import { defineConfig } from 'astro/config'; import netlify from '@astrojs/netlify/functions'; export default defineConfig({ output: 'server', adapter: netlify(), });
Edge Functions
Netlify has two serverless platforms, Netlify Functions and Netlify Edge Functions. With Edge Functions your code is distributed closer to your users, lowering latency.
To deploy with Edge Functions, use netlify/edge-functions
in the Astro config file instead of netlify/functions
.
// astro.config.mjs
import { defineConfig } from 'astro/config';
import netlify from '@astrojs/netlify/edge-functions';
export default defineConfig({
output: 'server',
adapter: netlify(),
});
Run middleware in Edge Functions
When deploying to Netlify Functions, you can choose to use an Edge Function to run your Astro middleware.
To enable this, set the build.excludeMiddleware
Astro config option to true
:
// astro.config.mjs
import { defineConfig } from 'astro/config';
import netlify from '@astrojs/netlify/functions';
export default defineConfig({
output: 'server',
adapter: netlify(),
build: {
excludeMiddleware: true,
},
});
Pass edge context to your site
Netlify Edge Functions provide a context object including metadata about the request, such as a user’s IP, geolocation data, and cookies.
To expose values from this context to your site, create a netlify-edge-middleware.ts
(or .js
) file in your project’s source directory. This file must export a function that returns the data to add to Astro’s locals
object, which is available in middleware and Astro routes.
In this example, visitorCountry
and hasEdgeMiddleware
would both be added to Astro’s locals
object:
// src/netlify-edge-middleware.ts
import type { Context } from 'https://edge.netlify.com';
export default function ({ request, context }: { request: Request; context: Context }) {
// Return serializable data to add to Astro.locals
return {
visitorCountry: context.geo.country.name,
hasEdgeMiddleware: true,
};
}
Note
Netlify Edge Functions run in a Deno environment, so import statements in this file must use Deno’s URL syntax.
netlify-edge-middleware.ts
must provide a function as its default export. This function:
- must return a JSON-serializable object, which cannot include types like
Map
,function
,Set
, etc. - will always run first, before any other middleware and routes.
- cannot return a response or redirect.
Per-page functions
The Netlify adapter builds to a single function by default. Astro 2.7 added support for splitting your build into separate entry points per page. If you use this configuration, the Netlify adapter will generate a separate function for each page. This can help reduce the size of each function so they are only bundling code used on that page.
// astro.config.mjs
import { defineConfig } from 'astro/config';
import netlify from '@astrojs/netlify/functions';
export default defineConfig({
output: 'server',
adapter: netlify(),
build: {
split: true,
},
});
Static sites
For static sites you usually don't need an adapter. However, if you use redirects
configuration in your Astro config, the Netlify adapter can be used to translate this to the proper _redirects
format.
import { defineConfig } from 'astro/config';
import netlify from '@astrojs/netlify/static';
export default defineConfig({
adapter: netlify(),
redirects: {
'/blog/old-post': '/blog/new-post',
},
});
Once you run astro build
there will be a dist/_redirects
file. Netlify will use that to properly route pages in production.
Note
You can still include a
public/_redirects
file for manual redirects. Any redirects you specify in the redirects config are appended to the end of your own.
On-demand Builders
Netlify On-demand Builders are serverless functions used to generate web content as needed that’s automatically cached on Netlify’s Edge CDN. You can enable their use, using the builders
configuration.
By default, all pages will be rendered on first visit and the rendered result will be reused for every subsequent visit until you redeploy. To set a revalidation time, call the runtime.setBuildersTtl(ttl)
local with the duration (in seconds).
As an example, for the following snippet, Netlify will store the rendered HTML for 45 seconds.
---
import Layout from '../components/Layout.astro';
if (import.meta.env.PROD) {
Astro.locals.runtime.setBuildersTtl(45);
}
---
<Layout title="Astro on Netlify">
{new Date(Date.now())}
</Layout>
It is important to note that On-demand Builders ignore query params when checking for cached pages. For example, if example.com/?x=y
is cached, it will be served for example.com/?a=b
(different query params) and example.com/
(no query params) as well.
Usage
Read the full deployment guide here.
After performing a build the netlify/
folder will contain Netlify Functions in the netlify/functions/
folder.
Now you can deploy. Install the Netlify CLI and run:
netlify deploy --build
The Netlify Blog post on Astro and the Netlify Documentation provide more information on how to use this integration to deploy to Netlify.
Configuration
To configure this adapter, pass an object to the netlify()
function call in astro.config.mjs
- there's only one possible configuration option:
dist
We build to the dist
directory at the base of your project. To change this, use the dist
option:
// astro.config.mjs
import { defineConfig } from 'astro/config';
import netlify from '@astrojs/netlify/functions';
export default defineConfig({
output: 'server',
adapter: netlify({
dist: new URL('./dist/', import.meta.url),
}),
});
And then point to the dist in your netlify.toml
:
[functions]
directory = "dist/functions"
builders
You can enable On-demand Builders using the builders
option:
// astro.config.mjs
import { defineConfig } from 'astro/config';
import netlify from '@astrojs/netlify/functions';
export default defineConfig({
output: 'server',
adapter: netlify({
builders: true,
}),
});
On-demand Builders are only available with the @astrojs/netlify/functions
adapter and are not compatible with Edge Functions.
binaryMediaTypes
This option is only needed for the Functions adapter and is not needed for Edge Functions.
Netlify Functions requires binary data in the body
to be base64 encoded. The @astrojs/netlify/functions
adapter handles this automatically based on the Content-Type
header.
We check for common mime types for audio, image, and video files. To include specific mime types that should be treated as binary data, include the binaryMediaTypes
option with a list of binary mime types.
// src/pages/image.jpg.ts
import fs from 'node:fs';
export function get() {
const buffer = fs.readFileSync('../image.jpg');
// Return the buffer directly, @astrojs/netlify will base64 encode the body
return new Response(buffer, {
status: 200,
headers: {
'content-type': 'image/jpeg',
},
});
}
Examples
-
The Astro Netlify Edge Starter provides an example and a guide in the README.
-
Browse Astro Netlify projects on GitHub for more examples!
Troubleshooting
For help, check out the #support
channel on Discord. Our friendly Support Squad members are here to help!
You can also check our Astro Integration Documentation for more on integrations.
Contributing
This package is maintained by Astro's Core team. You're welcome to submit an issue or PR!
Changelog
See CHANGELOG.md for a history of changes to this integration.