> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/withastro/astro/llms.txt
> Use this file to discover all available pages before exploring further.

# SSR and SSG

> Understanding Astro's rendering modes - static site generation, server-side rendering, and hybrid approaches

Astro offers flexible rendering modes that let you choose how each page in your project is built and delivered. You can use static site generation (SSG), server-side rendering (SSR), or combine both in a hybrid approach.

## Output Modes

Astro supports three output modes, configured in your `astro.config.mjs` file:

<CodeGroup>
  ```js astro.config.mjs - Static (Default) theme={null}
  import { defineConfig } from 'astro/config';

  export default defineConfig({
    output: 'static'
  });
  ```

  ```js astro.config.mjs - Server theme={null}
  import { defineConfig } from 'astro/config';
  import node from '@astrojs/node';

  export default defineConfig({
    output: 'server',
    adapter: node({
      mode: 'standalone'
    })
  });
  ```

  ```js astro.config.mjs - Hybrid theme={null}
  import { defineConfig } from 'astro/config';
  import node from '@astrojs/node';

  export default defineConfig({
    output: 'hybrid',
    adapter: node({
      mode: 'standalone'
    })
  });
  ```
</CodeGroup>

### Static Mode

**Default behavior.** All pages are pre-rendered at build time into static HTML files.

<Note>
  Static mode is ideal for content-heavy sites where pages don't change frequently, providing the best performance and lowest hosting costs.
</Note>

```astro src/pages/index.astro theme={null}
---
// This page is pre-rendered at build time
const data = await fetch('https://api.example.com/data').then(r => r.json());
---

<html>
  <body>
    <h1>Static Page</h1>
    <p>Built at: {new Date().toISOString()}</p>
  </body>
</html>
```

### Server Mode

**All pages rendered on-demand.** Pages are rendered on the server for each request, allowing for dynamic content and server-side logic.

<Warning>
  Server mode requires an adapter to deploy to your hosting platform.
</Warning>

```astro src/pages/api/user.astro theme={null}
---
// This page is rendered on every request
const { cookies } = Astro;
const userId = cookies.get('userId');

const user = await db.users.find(userId);
---

<html>
  <body>
    <h1>Welcome, {user.name}</h1>
    <p>Rendered at: {new Date().toISOString()}</p>
  </body>
</html>
```

### Hybrid Mode

**Mix static and server rendering.** Pages are pre-rendered by default, but you can opt-in to on-demand rendering for specific pages.

```astro src/pages/product/[id].astro theme={null}
---
export const prerender = false; // Opt-in to server rendering

const { id } = Astro.params;
const product = await db.products.find(id);
---

<html>
  <body>
    <h1>{product.name}</h1>
    <p>Real-time stock: {product.stock}</p>
  </body>
</html>
```

## Page-Level Control

You can control rendering per-page using the `prerender` export:

<Tabs>
  <Tab title="Server Mode">
    In `output: 'server'` mode, pages are server-rendered by default. Use `export const prerender = true` to pre-render specific pages:

    ```astro src/pages/about.astro theme={null}
    ---
    export const prerender = true; // Pre-render this page
    ---

    <html>
      <body>
        <h1>About Us</h1>
      </body>
    </html>
    ```
  </Tab>

  <Tab title="Hybrid Mode">
    In `output: 'hybrid'` mode, pages are pre-rendered by default. Use `export const prerender = false` for on-demand rendering:

    ```astro src/pages/dashboard.astro theme={null}
    ---
    export const prerender = false; // Server-render this page
    ---

    <html>
      <body>
        <h1>Dashboard</h1>
      </body>
    </html>
    ```
  </Tab>
</Tabs>

## Adapters

To use SSR, you need an adapter for your deployment platform. Adapters allow Astro's server output to work with your hosting provider's runtime.

### Official Adapters

<CardGroup cols={2}>
  <Card title="Node.js" icon="node-js" href="/integrations/adapters">
    Deploy to any Node.js server
  </Card>

  <Card title="Vercel" icon="triangle" href="/integrations/adapters">
    Deploy to Vercel's edge network
  </Card>

  <Card title="Netlify" icon="leaf" href="/integrations/adapters">
    Deploy to Netlify functions
  </Card>

  <Card title="Cloudflare" icon="cloud" href="/integrations/adapters">
    Deploy to Cloudflare Workers
  </Card>
</CardGroup>

### Installing an Adapter

<Steps>
  <Step title="Add the adapter">
    ```bash theme={null}
    npx astro add node
    ```
  </Step>

  <Step title="Configure output mode">
    The adapter will automatically configure your `astro.config.mjs`:

    ```js astro.config.mjs theme={null}
    import { defineConfig } from 'astro/config';
    import node from '@astrojs/node';

    export default defineConfig({
      output: 'server',
      adapter: node({
        mode: 'standalone'
      })
    });
    ```
  </Step>

  <Step title="Build and deploy">
    ```bash theme={null}
    npm run build
    ```

    Your server-rendered site is ready to deploy!
  </Step>
</Steps>

## Build Process

During the build process, Astro analyzes your routes and determines how each should be rendered based on your configuration:

<AccordionGroup>
  <Accordion title="Static Build">
    * All pages are rendered to HTML at build time
    * Assets are optimized and bundled
    * Output is a directory of static files ready to serve
    * Located in `dist/` by default
  </Accordion>

  <Accordion title="Server Build">
    * Creates a server entry point for on-demand rendering
    * Pre-renders pages marked with `prerender: true`
    * Bundles server-side code and dependencies
    * Outputs both static assets and server chunks
  </Accordion>
</AccordionGroup>

## When to Use Each Mode

<CardGroup cols={3}>
  <Card title="Static" icon="file">
    **Best for:**

    * Blogs and documentation
    * Marketing sites
    * Content-heavy sites
    * Maximum performance
  </Card>

  <Card title="Server" icon="server">
    **Best for:**

    * User dashboards
    * Personalized content
    * Real-time data
    * Authentication required
  </Card>

  <Card title="Hybrid" icon="layer-group">
    **Best for:**

    * E-commerce sites
    * SaaS applications
    * Mixed content types
    * Optimal flexibility
  </Card>
</CardGroup>

## Performance Considerations

<Tip>
  For optimal performance, pre-render as much as possible and use server rendering only where dynamic data is truly necessary.
</Tip>

### Static Generation Benefits

* **Fastest possible load times** - No server computation required
* **Easy to cache** - CDN-friendly static files
* **Lower hosting costs** - Simple file hosting
* **Better SEO** - Instant content availability

### Server Rendering Benefits

* **Fresh data** - Always up-to-date content
* **Personalization** - User-specific pages
* **Security** - Hide sensitive logic
* **Dynamic behavior** - Respond to request data

## Related Resources

<CardGroup cols={2}>
  <Card title="Adapters" icon="plug" href="/integrations/adapters">
    Learn about deployment adapters
  </Card>

  <Card title="Server Islands" icon="island-tropical" href="/features/server-islands">
    Mix static and dynamic content
  </Card>

  <Card title="Middleware" icon="filter" href="/features/middleware">
    Add server-side logic
  </Card>

  <Card title="Actions" icon="bolt" href="/features/actions">
    Handle form submissions
  </Card>
</CardGroup>
