Astro
Astro Netlify SSR Setup, Explained
Written by Noel
Published:
19 min read
Topics researched with AI assistance; reviewed and edited by Noel before publishing.

Explore this topic
More Astro guides, glossary entries, and practical workflows live on the topic hub.
Astro Netlify adapter SSR setup is the process of adding the official Netlify adapter to an Astro project so Netlify can serve on-demand rendered pages and related runtime features. In practical terms, it connects Astro’s build output to Netlify’s serverless and edge runtime so your site can do more than ship static HTML.
For a merchant site, documentation portal, or marketing site that needs dynamic pages, the adapter is what makes that deployment path work cleanly on Netlify.
Key takeaways
- Use the Netlify adapter when your Astro site needs on-demand rendering, server islands, actions, sessions, or other server-backed behavior on Netlify.
- A fully static Astro site does not need the adapter unless it depends on Netlify services that require a server, such as image handling.
- You can install the adapter with
astro add netlifyor add@astrojs/netlifymanually, then wire it intoastro.config.mjs.output: 'server'makes server rendering the default, while per-page on-demand rendering lets you keep static pages where they make sense.- Middleware, edge functions, and image settings can change how the site behaves, so setup is not just a one-line install.
What is it?
The Astro Netlify adapter is the official integration that prepares an Astro project for deployment on Netlify when you need runtime rendering. It tells Astro how to package your app so Netlify can serve pages that are rendered on demand instead of only at build time. That matters when a page depends on request-time logic, user state, or server features that static output cannot provide.
A simple example is a marketing site with mostly static pages but a few routes that need request-aware behavior. You might keep the homepage, blog index, and product pages static, while rendering a personalized support page or gated resource page on demand. The adapter gives Astro a deployment target that understands both sides of that mix.
The important distinction is that this is not required for every Astro project. If you are using Astro strictly as a static site builder and do not need Netlify server services, you can deploy without an adapter. The adapter becomes relevant when the project needs server rendering, edge behavior, or Netlify-specific features that depend on runtime execution.
In other words, the adapter is less about “making Astro work” and more about matching the project’s rendering model to the hosting platform. That is why the phrase astro netlify adapter ssr setup usually shows up when a team moves from static publishing to hybrid or server-rendered delivery.
A useful mental model is to think of the adapter as a translation layer. Astro writes the site in a framework-friendly way, but Netlify needs to know which parts should become functions, which parts can stay static, and how to route requests between them. The adapter handles that translation so the deployment target matches the app’s behavior.
It also helps teams avoid a common false assumption: that SSR is a single on/off switch. In Astro, SSR can be selective. One route can be prerendered, another can be rendered on demand, and a third can use middleware or edge logic. The adapter is what makes that mixed model deployable on Netlify without custom infrastructure.
Why it matters
The business value is straightforward: the adapter lets teams keep Astro’s performance benefits while adding the runtime behavior a real site sometimes needs. That can reduce the pressure to rebuild the whole project in a heavier application framework just to support a few dynamic routes. For merchants, that means a faster path to launch without giving up the ability to personalize, gate content, or use server-side logic where it matters.
Technically, it matters because deployment is where many “works locally” projects fail. An Astro app can be perfectly valid in development and still need the right adapter to deploy correctly to Netlify. The adapter aligns build output, runtime functions, and edge behavior so the platform can execute the app as intended.
It also matters for maintainability. If your team knows which routes are static and which rely on runtime rendering, you can make better decisions about caching, middleware, and image handling. That keeps the project easier to reason about than a site where every page is treated the same, even when the requirements are different.
For developers, the adapter is also a boundary-setting tool. It makes it clearer which features belong to the server runtime and which should remain static. That clarity helps when you are reviewing performance, debugging deployment issues, or deciding whether a feature belongs in middleware, an action, or a prerendered page.
There is also a practical cost angle. Static pages are usually cheaper and simpler to serve, while runtime pages introduce more moving parts. The adapter lets you reserve that complexity for the routes that actually need it instead of paying the operational cost across the whole site. That is especially valuable for content-heavy sites where only a small percentage of pages need request-time logic.
A second reason it matters is operational predictability. Once the adapter is in place, the team can reason about where code executes: at build time, at the edge, or in a serverless function. That distinction affects debugging, logging, and security reviews. For example, a redirect implemented in edge middleware behaves differently from one hard-coded into a page component, and the adapter makes that difference explicit.
It also helps when teams are planning growth. A site may start as a brochure site and later add sessions, gated downloads, or request-aware personalization. If the deployment path already supports those features, the team can evolve the site without a disruptive platform migration. That is often the real business win: not just shipping the first version, but keeping the architecture flexible enough for the next one.
How it works
The setup starts with Astro’s integration workflow. Astro provides an astro add command that can install official integrations automatically, including the Netlify adapter. If you prefer manual control, you can install @astrojs/netlify yourself and add it to astro.config.mjs. Either way, the goal is the same: tell Astro that Netlify is the deployment target and that server features should be packaged accordingly.
Once the adapter is in place, Astro changes how it builds the project. Instead of producing only static output, it can prepare on-demand rendered routes and runtime assets for Netlify’s environment. The build may produce a .netlify/ folder containing internal functions and edge functions, which Netlify then uses during deployment. That is the bridge between your Astro source code and the hosting platform’s execution model.
Static, server, and hybrid behavior
Astro gives you a few ways to shape rendering. You can enable on-demand rendering for specific pages, which keeps most of the site static while allowing selected routes to run on the server. You can also set output: 'server' if you want pages to be server-rendered by default. The adapter does not force one model; it enables the model you choose.
That flexibility is useful because not every route has the same cost or purpose. A blog post archive can often stay static, while a logged-in account page or request-sensitive page may need runtime rendering. The adapter lets you make that distinction without changing platforms.
Middleware and edge execution
By default, Astro middleware behaves differently depending on the page type. For prerendered pages, middleware is applied at build time. For on-demand rendered pages, it runs at runtime. If you need redirects, access control, or custom response headers for prerendered pages, you can set middlewareMode to edge so middleware runs on Netlify Edge Functions.
That changes the request path. Edge functions can inspect the request before the page is served, and for on-demand rendered pages the edge layer can pass serialized context.locals to the serverless function. Netlify also adds a security boundary here: the serverless function expects requests to come from the generated edge function, not directly from arbitrary sources.
Images and remote assets
The adapter also influences image handling. By default, it uses Netlify Image CDN to transform images on the fly without slowing builds. That is useful for sites with large image libraries or frequent content updates. If you do not want that behavior, you can disable it with the imageCDN option.
If your site loads remote images, you still need to authorize those domains or remote patterns in Astro config. That is a separate but related setup detail, and it is easy to miss when teams focus only on SSR. In practice, image configuration is part of the same deployment conversation because it affects whether the site renders correctly after deployment.
A subtle but important detail is that the adapter does not decide your architecture for you. It simply makes the architecture deployable. If your page logic depends on cookies, geolocation, or session state, the adapter gives Netlify a way to execute that logic at request time. If your page is static, the adapter does not add value by itself.
Another mechanism worth understanding is the split between build-time and request-time data. Static pages are generated once, so any data they use must be known during the build. On-demand rendered pages can read request-specific values such as headers, cookies, or geolocation data. The adapter is what allows Astro to preserve that distinction while still deploying through Netlify.
That split is why the adapter is often paired with careful route planning. If a page only needs dynamic data occasionally, you may not want to make the whole site server-rendered. Instead, you can keep the default static path and move only the request-dependent parts into on-demand routes or middleware. This is usually the most efficient way to use the adapter.
Use cases
The most common use case is a hybrid marketing or content site. Many teams want a fast static front end for the bulk of the site, but they also need a few server-powered routes for personalization, access control, or form handling. The adapter makes that possible without turning the whole project into a server-rendered app.
A second use case is content platforms with request-aware behavior. For example, a documentation site may need locale-aware routing, gated sections, or response headers that vary by request. In those cases, static output alone is not enough, and the adapter gives Astro the runtime support to handle those needs on Netlify.
A third use case is product or campaign pages that rely on Netlify services. The SERP research notes that if you are using Astro as a static site builder, you only need the adapter if you are using additional Netlify services that require a server, such as Netlify Image CDN. That makes the adapter relevant even when the site is mostly static, because one server-backed dependency can change the deployment requirement.
For merchants, the decision often comes down to whether the site needs request-time logic. If the answer is yes, the adapter is usually part of the deployment plan. If the answer is no, the simpler static path is often better.
A fourth scenario is internal tooling or partner portals built on Astro. These projects often start as content sites but gradually pick up authentication, session-aware navigation, or role-based access. The adapter lets teams add those capabilities without abandoning the Astro codebase they already have.
There is also a useful split between “public content” and “private or contextual content.” Public pages such as landing pages, blog posts, and evergreen documentation are often ideal for prerendering. Private dashboards, account pages, and request-sensitive landing pages are better candidates for on-demand rendering. The adapter lets you combine both patterns in one deployment.
That combination is especially helpful for teams that care about SEO and performance at the same time. Search-facing pages can remain static and fast, while user-specific pages can still be dynamic. In practice, that means you do not have to choose between a performant marketing site and a functional application surface.
How to implement or apply it
The cleanest setup starts with deciding whether you want automatic or manual installation. If you are moving quickly or setting up a standard project, astro add netlify is the simplest route because it installs @astrojs/netlify and updates the Astro config in one step. If your project has a carefully managed config or you want to review each change, install the package manually and edit the config yourself.
A basic manual setup follows the same pattern the docs describe: install the package, import the adapter, and add adapter: netlify() inside defineConfig. From there, decide whether your site should use on-demand rendering per page or server mode globally. That choice should be based on how much of the site truly needs runtime rendering.
A practical setup workflow
Start by auditing your routes. Mark which pages are static, which need request-time data, and which depend on middleware or sessions. Then decide whether the site should remain mostly static with a few dynamic routes, or whether server rendering should be the default. That decision affects both performance and complexity.
Next, review middleware requirements. If you need redirects, access control, or response headers to apply before prerendered pages are served, set middlewareMode: 'edge'. If you do not need that behavior, keep the default model and avoid adding edge complexity you will not use.
After that, check image behavior. If you want Netlify Image CDN, leave it enabled. If you need a different image pipeline, disable it explicitly and configure Astro image domains or remote patterns as needed. This is one of those details that can be overlooked until a deployment fails or images stop loading as expected.
Finally, build locally before deploying. The docs note that a local build will produce the Netlify output folder, which is a useful checkpoint. Once the build is clean, use the Netlify CLI to deploy. That sequence helps catch config issues before they become production problems.
Decision criteria for teams
Use the adapter when the site needs on-demand rendering, server islands, actions, sessions, or Netlify-specific runtime services. Skip it when the site is fully static and does not rely on server-backed features. If you are unsure, the right question is not “Do we use Astro?” but “Does this deployment need runtime execution on Netlify?”
That framing keeps the setup practical. It avoids over-engineering static sites and prevents under-configuring dynamic ones. For teams building Astro projects professionally, that is the difference between a deployment that feels fragile and one that is easy to maintain.
A good implementation habit is to document the rendering choice beside each route. When a teammate later adds a page, they should know whether it belongs in the static build, the on-demand layer, or the edge middleware path. That small bit of documentation prevents accidental regressions during future content or feature updates.
It also helps to keep the first deployment intentionally small. Start with one dynamic route, confirm that the adapter is packaging it correctly, and then expand to other routes once the behavior is proven. That reduces the chance of debugging several moving parts at once. For teams with mixed skill levels, this staged rollout is often safer than flipping the entire site to server mode on day one.
Common mistakes and pitfalls
The biggest mistake is assuming every Astro site needs the adapter. The docs are explicit that a static Astro site does not need it unless it uses additional Netlify services that require a server. Installing the adapter everywhere by default can add complexity without solving a real problem.
Another common issue is choosing server mode without checking whether the site actually needs it. output: 'server' is useful when server rendering should be the default, but it is not a free upgrade. If most pages can be prerendered, keeping them static is often simpler and easier to cache.
Middleware configuration is another place where teams get tripped up. If you need redirects or access control on prerendered pages, you must understand the difference between build-time middleware and edge execution. Without middlewareMode: 'edge', you may expect request-aware behavior that never runs where you need it.
Image settings can also cause confusion. The adapter’s default use of Netlify Image CDN is helpful, but it is still a deployment assumption. If your remote images are not authorized through Astro config, the site may build but fail to render assets correctly in production.
A final pitfall is treating local success as proof of deployment readiness. With adapters, the local build output matters because it reveals how Astro is packaging the app for Netlify. If the build step is not clean, deployment issues are usually not far behind.
Another subtle mistake is mixing prerendered and runtime pages without checking shared code paths. A helper that works in a server route may rely on request data that does not exist during prerendering. When that happens, the site can fail in ways that look random unless you separate build-time and runtime assumptions early.
Teams also sometimes forget that edge middleware and serverless rendering are different layers. A redirect that works in one layer may not behave the same way in another, especially when cookies or headers are involved. If a route depends on request context, verify which layer owns that logic before you ship it.
Best practices and quick checklist
The best practice is to keep the rendering model as simple as the project allows. Static pages should stay static. Dynamic pages should be dynamic for a reason. That separation makes the Astro Netlify adapter SSR setup easier to maintain and easier to debug later.
A good second practice is to document which features depend on Netlify runtime support. If a teammate later removes the adapter or changes middleware settings, that dependency should be obvious. This is especially important on content-heavy sites where the runtime behavior is not visible from the homepage.
Another best practice is to test the deployment path, not just the local dev path. Build locally, inspect the generated Netlify artifacts, and confirm that the pages you expect to be dynamic are actually routed through the adapter. That is the fastest way to catch mismatches between intent and configuration.
Quick checklist
- Confirm whether the site truly needs on-demand rendering or server mode.
- Install the adapter with
astro add netlifyor add@astrojs/netlifymanually. - Update
astro.config.mjswith the adapter and any rendering options. - Decide whether middleware should run at the edge.
- Review image CDN behavior and remote image authorization.
- Build locally before deploying to Netlify.
- Verify any request-dependent pages after deployment.
- Keep route-level rendering decisions documented for future edits.
If you are managing a broader Astro stack, it can also help to pair this setup with a clear content architecture. A structured content model makes it easier to decide which routes stay static and which routes need runtime behavior. For that, the content collections guide is a useful companion.
A final best practice is to revisit the setup when requirements change. A site that starts as static may later need sessions, edge redirects, or image processing, and those additions can change the ideal adapter configuration. Treat the setup as part of the architecture, not a one-time install.
From practice — illustrative scenario (hypothetical, not a client project)
Illustrative example — not a real client project: imagine a merchant launching a product education site in Astro. The site has a static homepage, a blog, and several campaign pages, but it also needs a member-only resource area, request-based redirects for older campaign URLs, and image transformations for a large library of product visuals.
At first, the team might try to keep everything static because the site feels like a marketing build. That works for the public pages, but the gated resources and redirects create a problem: the static output cannot reliably handle request-time access checks or response logic. The team then evaluates whether to move the whole site to a heavier framework or keep Astro and add the Netlify adapter.
The practical approach is to keep the public pages prerendered and enable on-demand rendering only where needed. Middleware is configured to run on Netlify Edge Functions so redirects and access control can happen before the page is served. The team also leaves Netlify Image CDN enabled because the site depends on many remote and transformed images, which would otherwise add build overhead.
A sensible workflow in this scenario would be to map each route into one of three buckets: static, on-demand, or edge-dependent. The homepage and blog stay static. The member resource area becomes on-demand rendered because it needs request-time checks. Redirect logic moves to edge middleware because it must run before the request reaches the page. That simple classification keeps the setup understandable.
The team would then test the site in the same order a visitor experiences it: first the redirect, then the access gate, then the page render, then the image load. If any step fails, the fix is usually in the boundary between static and runtime behavior rather than in the page content itself. That is why the adapter is valuable: it makes those boundaries explicit.
A useful implementation detail in this scenario is to define ownership for each feature. Redirects belong to edge middleware, access checks belong to the on-demand route, and image behavior belongs to the adapter configuration. When those responsibilities are separated clearly, debugging becomes much easier because each problem has a likely layer and a likely fix.
The team might also create a short deployment checklist for future contributors: confirm the route is in the right rendering mode, confirm the middleware still runs at the edge, confirm the image pipeline is still enabled, and confirm the local build matches the Netlify output. That kind of checklist is simple, but it prevents accidental regressions when the site grows.
The takeaway is not that every feature should be server-rendered. It is that the adapter lets the team choose where runtime behavior belongs. That keeps the site fast for visitors, manageable for developers, and easier to evolve when the next feature request arrives.
Related concepts and further reading
If you are deciding whether to stay static or add runtime behavior, these related guides help connect the deployment choice to the rest of the Astro stack.
- Astro content collections guide — useful when your rendering strategy depends on clean content modeling.
- Astro islands architecture — helpful context for keeping interactive parts isolated.
- Astro Themes — browse Astro-ready starting points when you want a faster launch path.
- Northframe — a theme option for teams building a polished Astro site with a clean structure.
- Netlify deployment guide — official deployment reference for the Netlify target.
Explore this topic
More Astro guides, glossary entries, and practical workflows live on the topic hub.
Frequently asked questions
When do I need the Astro Netlify adapter?
You need the adapter when your Astro site uses on-demand rendering features on Netlify, such as server-rendered pages, server islands, actions, or sessions. If your site is fully static and does not rely on Netlify server features, you may not need it. The adapter prepares Astro’s build output for Netlify’s runtime environment.
Can I install the Netlify adapter automatically?
Yes. Astro supports an `astro add` command that can install official integrations and update your config for you. You can also install `@astrojs/netlify` manually if you prefer to control the setup step by step. Both approaches lead to the same adapter being added to the project.
Does the adapter make every Astro page server-rendered?
Not necessarily. You can enable on-demand rendering per page or set `output: 'server'` to server-render pages by default. That means you can mix static and server-rendered behavior depending on the project’s needs. The adapter supports either approach on Netlify.
What is middlewareMode edge used for?
`middlewareMode: 'edge'` runs Astro middleware on Netlify Edge Functions instead of only at build time for prerendered pages. This is useful for redirects, access control, and custom response headers that need to apply before the page is served. It also affects how requests are handled across static, prerendered, and on-demand pages.
Does the Netlify adapter help with images?
By default, the adapter uses Netlify Image CDN to transform images on the fly without increasing build times. If you do not want that behavior, you can opt out with the `imageCDN` option. For remote images, you still need to authorize domains or remote patterns in Astro config.