# How to Use the Gatsby Slice API for Partial Hydration and Large Site Performance

> Master the Gatsby Slice API for partial hydration and boost large site performance. Ship less JavaScript, reduce build times, and shrink bundle sizes with this powerful feature.

- Repository: [Gatsby/gatsby](https://github.com/gatsbyjs/gatsby)
- Tags: how-to-guide
- Published: 2026-03-06

---

**The Gatsby Slice API lets you build shared UI components once and stitch them into thousands of pages, while Partial Hydration (Beta) ensures only interactive slices ship JavaScript to the browser, reducing incremental build times by up to 90% and dramatically shrinking bundle sizes.**

Gatsby 5 introduced the **Slice API** alongside **Partial Hydration (Beta)** to eliminate performance bottlenecks on large sites. According to the `gatsbyjs/gatsby` source code, this architecture extracts highly-shared components—such as headers, footers, and cards—into discrete build units that render once and stitch into every page. By implementing the Gatsby Slice API for partial hydration, you generate static HTML for non-interactive content while shipping JavaScript only for components that require client-side interactivity, resulting in significantly faster builds and smaller browser payloads.

## How the Slice API Works Internally

The Slice API operates through a deterministic build pipeline defined in the Gatsby core. When you call `createSlice` in [`gatsby-node.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-node.js), the system validates the component, generates a unique identifier, and manages rendering through specialized workers and webpack plugins.

### Slice Registration and Validation

In [`packages/gatsby/src/redux/actions/restricted.ts`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby/src/redux/actions/restricted.ts), the `createSlice` action validates the `id`, `component` path, and optional `context` before registering the slice in the internal Redux store as type `IGatsbySlice`. The [`packages/gatsby/src/utils/slices.ts`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby/src/utils/slices.ts) utility provides `getSliceId`, which generates a deterministic slice ID from the component chunk name and a content digest of the slice context. This ensures that identical slices produce identical IDs across builds, enabling aggressive caching.

### Build-Time Rendering and Stitch Directives

During the HTML build phase, Gatsby renders each slice exactly once. The [`packages/gatsby/src/utils/worker/child/render-html.ts`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby/src/utils/worker/child/render-html.ts) worker executes `renderPartialHydrationProd` to generate static HTML for every slice, saving these as discrete static files. When constructing individual pages, Gatsby replaces the `<Slice alias="…">` placeholder with a **stitch directive** that points to the pre-rendered slice HTML, avoiding redundant rendering of shared components across thousands of pages.

### Partial Hydration Integration

When you enable Partial Hydration via `flags.PARTIAL_HYDRATION`, the [`packages/gatsby/src/utils/webpack/plugins/partial-hydration.ts`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby/src/utils/webpack/plugins/partial-hydration.ts) plugin (implemented as `PartialHydrationPlugin`) analyzes slice components. It emits **partial-hydration chunks** only for slices containing client-side code (marked with `"use client"`), while keeping purely static slices as raw HTML. At runtime, [`packages/gatsby/src/components/slice.tsx`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby/src/components/slice.tsx) lazy-loads JavaScript exclusively for interactive slices, leaving static markup untouched in the DOM.

## Implementing Slices for Partial Hydration

To leverage the performance benefits, you must define slices at the data layer, place them in your layouts, and configure the Partial Hydration flag.

### Defining Slices in gatsby-node.js

Use `actions.createSlice` to register shared components. The `id` identifies the slice globally, while `context` passes data to the component as `sliceContext`.

```javascript
exports.createPages = async ({ actions }) => {
  actions.createSlice({
    id: `site-header`,
    component: require.resolve(`./src/components/header.js`),
    context: { siteTitle: `My Awesome Site` },
  })
}

```

This registration occurs in [`packages/gatsby/src/redux/actions/restricted.ts`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby/src/redux/actions/restricted.ts), where the action creator validates that the component path exists and the ID is unique.

### Rendering Slices with the Slice Component

Import the `Slice` component from `gatsby` and use the `alias` prop to reference your slice. The alias defaults to the slice ID if omitted.

```javascript
import { Slice } from "gatsby"
import { Footer } from "./footer"

export const Layout = ({ children }) => (
  <div className="layout">
    <Slice alias="site-header" />
    {children}
    <Footer />
  </div>
)

```

At build time, Gatsby replaces this placeholder with a stitch directive pointing to the pre-rendered HTML generated by the worker in [`packages/gatsby/src/utils/worker/child/render-html.ts`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby/src/utils/worker/child/render-html.ts).

### Mapping Aliases for Dynamic Content

You can map generic aliases to specific slice IDs on a per-page basis. This is useful when the same layout requires different slice instances for different pages.

```javascript
exports.createPages = ({ actions }) => {
  const animals = ['dog', 'cat', 'giraffe']

  animals.forEach(animal => {
    actions.createSlice({
      id: `animal-image-${animal}`,
      component: require.resolve(`./src/components/animal-image.js`),
      context: { animal },
    })

    actions.createPage({
      path: `/animals/${animal}`,
      component: require.resolve(`./src/templates/animal-page.js`),
      slices: {
        'animal-image': `animal-image-${animal}`,
      },
    })
  })
}

```

The `slices` object in `createPage` maps the alias used in your JSX to the specific slice ID registered for that page.

### Adding GraphQL Queries to Slices

Slices support static queries that receive context variables via the `sliceContext` prop. Export a GraphQL query using the variable names passed in `createSlice`.

```javascript
import * as React from "react"
import { graphql } from "gatsby"

export const query = graphql`
  query ($siteTitle: String) {
    site {
      siteMetadata {
        title
        description
      }
    }
  }
`

export default function Header({ data, sliceContext }) {
  return (
    <header>
      <h1>{sliceContext.siteTitle}</h1>
      <p>{data.site.siteMetadata.description}</p>
    </header>
  )
}

```

The query executes at build time, and the `$siteTitle` variable is populated from the `context` object passed to `createSlice`.

### Enabling Partial Hydration (Beta)

To activate Partial Hydration and prevent static slices from shipping JavaScript, add the flag to [`gatsby-config.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-config.js).

```javascript
module.exports = {
  flags: {
    PARTIAL_HYDRATION: true,
  },
}

```

With this enabled, the `PartialHydrationPlugin` in [`packages/gatsby/src/utils/webpack/plugins/partial-hydration.ts`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby/src/utils/webpack/plugins/partial-hydration.ts) analyzes each slice's imports. Only slices containing React Server Components with client directives receive JavaScript chunks; all others remain as static HTML stitched into the page.

## Performance Impact on Large Sites

According to the Gatsby 5 release notes and implementation in [`packages/gatsby/src/utils/slices.ts`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby/src/utils/slices.ts), the Slice API delivers substantial optimizations:

- **Faster Incremental Builds**: Changing a highly shared component (like a navigation bar) triggers only the slice rebuild, not a full rebuild of every referencing page. This achieves up to 90% reduction in incremental build times for content changes in shared components.
- **Reduced JavaScript Payloads**: Partial Hydration ensures browsers download JavaScript only for interactive slices. Static headers, footers, and content cards ship as HTML with zero client-side overhead, improving First Contentful Paint and Interaction Ready metrics.
- **Deterministic Caching**: The `getSliceId` utility creates content-based hashes, ensuring unchanged slices persist across builds while modified slices invalidate precisely.

## Summary

- The **Slice API** extracts shared UI components into single-render units that stitch into pages via HTML directives, defined in [`packages/gatsby/src/redux/actions/restricted.ts`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby/src/redux/actions/restricted.ts) and rendered in [`packages/gatsby/src/utils/worker/child/render-html.ts`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby/src/utils/worker/child/render-html.ts).
- **Partial Hydration**, controlled by `flags.PARTIAL_HYDRATION` and implemented in [`packages/gatsby/src/utils/webpack/plugins/partial-hydration.ts`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby/src/utils/webpack/plugins/partial-hydration.ts), restricts JavaScript bundling to only those slices containing interactive code.
- Use `actions.createSlice` with `id`, `component`, and optional `context` to register slices, then render them with `<Slice alias="id">` in your layouts.
- Map dynamic aliases per page using the `slices` option in `actions.createPage` for flexible, data-driven layouts.
- Combine both features to achieve up to 90% faster builds on large sites while minimizing client-side JavaScript execution.

## Frequently Asked Questions

### What is the difference between a Slice and a regular React component?

A **Slice** is a React component extracted at build time by Gatsby's rendering pipeline. Unlike standard components that render as part of each page's bundle, slices generate deterministic IDs via `getSliceId` in [`packages/gatsby/src/utils/slices.ts`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby/src/utils/slices.ts) and render once into static HTML. This allows Gatsby to stitch the same HTML into multiple pages without re-rendering the component for every page build.

### How does Partial Hydration determine which slices receive JavaScript?

The **PartialHydrationPlugin** in [`packages/gatsby/src/utils/webpack/plugins/partial-hydration.ts`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby/src/utils/webpack/plugins/partial-hydration.ts) scans slice components for the `"use client"` directive or client-side imports. Slices containing such markers compile into separate JavaScript chunks loaded by [`packages/gatsby/src/components/slice.tsx`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby/src/components/slice.tsx) at runtime. Purely static slices without client code remain as server-rendered HTML with no browser JavaScript overhead.

### Can I pass dynamic data to a Slice without triggering full hydration?

Yes. Pass data via the `context` option in `createSlice`, which becomes available as `sliceContext`. For static data, export a GraphQL query from the slice component using variables matching your context keys. This data resolves at build time, keeping the slice static unless you explicitly add interactive client components.

### What happens to my site when I update a component used in multiple slices?

Gatsby rebuilds only the affected slice based on its content digest and ID generation logic in [`packages/gatsby/src/utils/slices.ts`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby/src/utils/slices.ts). Because pages reference slices through stitch directives rather than embedding the component directly, updating a shared navigation slice does not rebuild every page that displays it—only the slice file regenerates, and pages receive the new HTML via updated stitch references.