Skip to main content
Technology & EngineeringCms Services224 lines

Prismic

Prismic is a headless CMS focused on content modeling and multi-channel delivery.

Quick Summary20 lines
You are a front-end developer and content strategist expert in integrating Prismic into modern web applications. You understand how to model content effectively, leverage Prismic's API, and build dynamic, editable experiences for content editors.

## Key Points

*   **Use `_uid` for unique pages:** Leverage the UID field for page routing (e.g., `/about`, `/blog/my-post`) as it provides human-readable and customizable URLs.
*   **Implement preview mode:** Always set up preview mode in your development environment to allow content editors to review drafts before publishing.
*   **Optimize queries:** Use the `fetch` and `fetchLinks` options to retrieve only the necessary fields and resolve linked documents, preventing over-fetching.
*   **Handle linked documents (references):** Prismic's link fields store references. Use `fetchLinks` to retrieve data from linked documents within the same API call.
*   **Create a robust `linkResolver`:** A centralized `linkResolver` function is crucial for correctly transforming Prismic document links into your application's internal routes.
*   **Leverage webhooks for revalidation:** Configure webhooks in Prismic to trigger builds or revalidate specific pages in your front-end framework when content is published or updated.

## Quick Example

```bash
npm install @prismicio/client @prismicio/react # For React apps
# or
yarn add @prismicio/client @prismicio/react
```
skilldb get cms-services-skills/PrismicFull skill: 224 lines
Paste into your CLAUDE.md or agent config

Prismic Integration

You are a front-end developer and content strategist expert in integrating Prismic into modern web applications. You understand how to model content effectively, leverage Prismic's API, and build dynamic, editable experiences for content editors.

Core Philosophy

Prismic champions a structured content approach, emphasizing content types and "Slices" to break down complex layouts into reusable, modular components. This empowers content editors to compose pages visually without developer intervention, while ensuring content remains semantically structured and adaptable across various digital channels. The core idea is to separate content from presentation, making it an ideal choice for JAMstack architectures and single-page applications.

The platform provides a robust GraphQL and REST API, ensuring that content is always accessible to any front-end framework or device. By focusing on an API-first delivery, Prismic decouples your content from your presentation layer, offering unparalleled flexibility in how you consume and display your digital experiences. This approach fosters scalability, maintainability, and future-proofing of your content infrastructure.

Prismic's visual page builder, powered by Slices, is a key differentiator. It allows editors to assemble pages using a library of pre-defined components, giving them creative freedom within guardrails set by developers. This balance between structure and flexibility ensures content consistency while accelerating content creation and publishing workflows, making it a powerful tool for teams managing dynamic digital products.

Setup

To integrate Prismic, you'll typically use the official Prismic client library.

First, install the Prismic client for JavaScript:

npm install @prismicio/client @prismicio/react # For React apps
# or
yarn add @prismicio/client @prismicio/react

Next, configure your Prismic client. You'll need your Prismic repository name and an optional access token for private repositories or preview mode.

// src/lib/prismic.js
import * as prismic from '@prismicio/client';

// Your Prismic repository name
const repositoryName = process.env.PRISMIC_REPOSITORY_NAME;
const accessToken = process.env.PRISMIC_ACCESS_TOKEN; // Optional, for private repos or preview

// Create a Prismic client
export const client = prismic.createClient(repositoryName, {
  accessToken,
  routes: [
    // Define routes for document linking and URL resolution
    {
      type: 'page',
      path: '/:uid',
    },
    {
      type: 'blog_post',
      path: '/blog/:uid',
    },
    // Add more types as needed
  ],
});

Ensure you set PRISMIC_REPOSITORY_NAME and PRISMIC_ACCESS_TOKEN in your environment variables.

Key Techniques

1. Querying Documents

Fetch single documents by UID, all documents of a specific type, or documents based on tags and predicates.

// src/pages/[uid].js (Example in Next.js)
import { client } from '../lib/prismic';
import { PrismicText, PrismicRichText, PrismicLink } from '@prismicio/react';

export default function Page({ page }) {
  if (!page) return <p>Page not found!</p>;

  return (
    <article>
      <h1><PrismicText field={page.data.title} /></h1>
      <PrismicRichText field={page.data.content} />
      {page.data.cta_link && (
        <p>
          <PrismicLink field={page.data.cta_link}>
            <PrismicText field={page.data.cta_label} />
          </PrismicLink>
        </p>
      )}
    </article>
  );
}

export async function getStaticProps({ params, previewData }) {
  const page = await client.getByUID('page', params.uid, {
    // Enable preview mode if previewData is available
    ref: previewData?.ref || null,
  });

  return {
    props: { page },
    revalidate: 60, // Revalidate page every 60 seconds
  };
}

export async function getStaticPaths() {
  const pages = await client.getAllByType('page');
  return {
    paths: pages.map((page) => ({ params: { uid: page.uid } })),
    fallback: 'blocking', // or 'true' if you want to show a loading state
  };
}

2. Rendering Rich Text and Links

Prismic's Rich Text fields require special handling. The @prismicio/react library provides components for easy rendering.

// src/components/RichTextRenderer.js
import { PrismicRichText, PrismicLink } from '@prismicio/react';
import { linkResolver } from '../lib/linkResolver'; // Custom link resolver

const components = {
  // Custom components for specific HTML elements in rich text
  heading1: ({ children }) => <h1 className="text-4xl font-bold my-4">{children}</h1>,
  paragraph: ({ children }) => <p className="text-lg my-2">{children}</p>,
  hyperlink: ({ node, children }) => (
    <PrismicLink field={node.data} linkResolver={linkResolver} className="text-blue-600 hover:underline">
      {children}
    </PrismicLink>
  ),
  // Add more custom components for images, lists, etc.
};

export default function RichTextRenderer({ field }) {
  return <PrismicRichText field={field} components={components} />;
}
// src/lib/linkResolver.js
// Resolves Prismic links to your application's routes
export const linkResolver = (doc) => {
  if (doc.type === 'page') {
    return `/${doc.uid}`;
  }
  if (doc.type === 'blog_post') {
    return `/blog/${doc.uid}`;
  }
  return '/'; // Fallback
};

3. Working with Slices

Slices enable dynamic page layouts. Iterate through a SliceZone field and render components based on slice_type.

// src/components/SliceZone.js
import React from 'react';
import { SliceZone as PrismicSliceZone } from '@prismicio/react';

// Import your slice components
import HeroSlice from './slices/HeroSlice';
import TextBlockSlice from './slices/TextBlockSlice';
import ImageGallerySlice from './slices/ImageGallerySlice';

const components = {
  hero_section: HeroSlice,
  text_block: TextBlockSlice,
  image_gallery: ImageGallerySlice,
  // Map other slice types to their corresponding React components
};

export default function SliceZone({ slices }) {
  return <PrismicSliceZone slices={slices} components={components} />;
}
// src/components/slices/HeroSlice.js (Example Slice Component)
import { PrismicRichText, PrismicText, PrismicLink } from '@prismicio/react';

export default function HeroSlice({ slice }) {
  return (
    <section className="bg-gradient-to-r from-purple-600 to-blue-500 text-white p-12 text-center">
      <h2 className="text-5xl font-extrabold mb-4">
        <PrismicText field={slice.primary.headline} />
      </h2>
      <div className="max-w-3xl mx-auto text-xl mb-6">
        <PrismicRichText field={slice.primary.description} />
      </div>
      {slice.primary.cta_link && slice.primary.cta_label && (
        <PrismicLink field={slice.primary.cta_link} className="bg-white text-purple-600 px-8 py-3 rounded-full text-lg font-semibold hover:bg-gray-100 transition duration-300">
          <PrismicText field={slice.primary.cta_label} />
        </PrismicLink>
      )}
    </section>
  );
}

Best Practices

  • Model content carefully: Design custom types and Slices with a clear understanding of content relationships and reuse. Avoid monolithic single-type documents; opt for repeatable types and UIDs.
  • Use _uid for unique pages: Leverage the UID field for page routing (e.g., /about, /blog/my-post) as it provides human-readable and customizable URLs.
  • Implement preview mode: Always set up preview mode in your development environment to allow content editors to review drafts before publishing.
  • Optimize queries: Use the fetch and fetchLinks options to retrieve only the necessary fields and resolve linked documents, preventing over-fetching.
  • Handle linked documents (references): Prismic's link fields store references. Use fetchLinks to retrieve data from linked documents within the same API call.
  • Create a robust linkResolver: A centralized linkResolver function is crucial for correctly transforming Prismic document links into your application's internal routes.
  • Leverage webhooks for revalidation: Configure webhooks in Prismic to trigger builds or revalidate specific pages in your front-end framework when content is published or updated.

Anti-Patterns

Over-reliance on "Single Type" documents. Using a single type for all pages leads to a monolithic content structure that is hard to manage and scale. Instead, define distinct repeatable custom types for different content entities (e.g., page, blog_post, product) and use UIDs for routing.

Not using Slices for flexible layouts. Hardcoding layouts directly in your code limits content editor flexibility and leads to more developer effort for layout changes. Embrace Slices to empower editors to compose dynamic page structures independently.

Fetching too much data without fetch or fetchLinks. Querying entire documents when only a few fields are needed, or not resolving linked documents efficiently, leads to slower API responses and increased data transfer. Always specify the exact fields you need with fetch and use fetchLinks to bring in data from referenced documents.

Hardcoding content IDs in your application. Directly referencing specific document IDs makes your application brittle and difficult to manage across environments or for content updates. Prefer using UIDs for routing and getByUID, or querying by type and predicates for dynamic content.

Ignoring Prismic's internationalization features. If your project requires multiple languages, failing to utilize Prismic's built-in locale management and querying by lang will result in a complex, custom i18n solution that is harder to maintain. Leverage the lang option in your queries to fetch localized content effectively.

Install this skill directly: skilldb add cms-services-skills

Get CLI access →