Up to this point in the course, we have been working in SSG (Static Site Generation) mode.
In this mode, when we run npm run build, Astro generates a dist/ folder full of HTML files. If you have a blog, that’s perfect. You upload those files to any server and you’re done.
But, what if we need to know who the user visiting the website is? Or if we want to show the Bitcoin price in real time? Or read session cookies?
A static HTML file cannot do that. We need the server to “think” and generate the page at the moment the user requests it.
This is Server Side Rendering (SSR).
Output modes (output)
Astro has three operating modes that we define in astro.config.mjs under the output property.
output: 'static' (Default)
This is what we have used so far.
- When it’s built: At build time.
- Speed: Maximum (it’s just serving files).
- Cost: Minimum.
- Use case: Blogs, portfolios, landing pages, documentation.
output: 'server' (Pure SSR)
Turns your project into a server application. Every time someone visits your site, the server executes the code, queries the database, and generates the HTML.
- When it’s built: On each request (Request time).
- Speed: Depends on your code and database.
- Capabilities: Access to Cookies, Headers, private APIs, dynamic content.
- Use case: SaaS, social networks, dynamic e-commerce.
output: 'hybrid' (The sweet spot)
This is a great feature of Astro. It maintains Static by default behavior, but allows you to mark certain pages as dynamic.
- Use case: You have a blog (static) but want a
/loginpage and a/profilepage (dynamic).
Summary: What do I choose?
| Need | Mode (output) | Adapter |
|---|---|---|
| Personal blog, documentation, portfolio | static | None (or the hosting provider’s for extra features) |
| Corporate website with a contact form | hybrid | Node / Vercel / Netlify |
| Dashboard, SaaS, Social Network | server | Node / Vercel / Netlify |
| Online Store | server or hybrid | Node / Vercel / Netlify |
Activating SSR mode
To switch modes, we edit our configuration file:
// astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
output: 'server', // Or 'hybrid'
});
If you save this and try to build, Astro will give you a warning. A key piece is missing: The Adapter.
When you generate static HTML, it doesn’t matter where you host it. HTML is standard.
But when you use SSR, you are running JavaScript code on the server. And not all servers are the same.
- Node.js expects a classic HTTP server.
- Vercel uses “Serverless Functions” with a specific syntax.
- Cloudflare uses “Workers” on the edge with a runtime that is not Node.
Astro doesn’t know where you are going to deploy your site. That’s why you need to install an Adapter that acts as a translator between Astro and your hosting provider.
Installing an Adapter
Just like with React or Tailwind, we use the astro add command.
For VPS or local servers (Node.js)
If you are going to host your site on your own server, in a Docker container, or on a service like DigitalOcean or Railway.
npx astro add node
For the cloud (Vercel / Netlify)
If you use automatic deployment platforms (“Serverless”).
npx astro add vercel
# or
npx astro add netlify
Astro will automatically configure the adapter in your astro.config.mjs:
import { defineConfig } from 'astro/config';
import node from '@astrojs/node';
export default defineConfig({
output: 'server',
adapter: node({
mode: 'standalone', // Creates a standalone server
}),
});
Code changes: The Astro.request object
Once SSR is activated, we gain access to new capabilities in the frontmatter of our components.
Now we can read request headers or cookies:
---
// src/pages/perfil.astro
// Only in SSR mode can we access cookies
const usuarioCookie = Astro.cookies.get('user_session');
if (!usuarioCookie) {
// We can redirect from the server
return Astro.redirect('/login');
}
const usuario = await buscarEnBaseDeDatos(usuarioCookie.value);
---
<h1>Hello again, {usuario.nombre}</h1>
Goodbye to getStaticPaths!
In a purely SSR page (output: 'server'), we no longer export getStaticPaths for dynamic routes ([id].astro).
Since the page is generated on the fly, Astro reads the ID directly from the URL (Astro.params.id) and you are responsible for fetching the data at that moment.
The move to SSR is exciting because it’s where the web becomes “smart”. Now that we have a server, we can start building APIs.
Yes, you read that right. In the next article, we’ll see how to use Astro to create your own API Endpoints that return JSON instead of HTML.
