Taxonomies
Learn how to create taxonomies with Next.js an Prismic.
Taxonomies define how you organize content. Categories are a common form of taxonomy. This guide describes a scalable way to create a category taxonomy within Prismic using content relationships. Content relationships allow you to link between Prismic documents and retrieve data. You will be able to template a list of all categories, a list of categories used in a page, and display a page’s categories.
The content models you’ll build throughout this guide support the following key features:
- Manage your categories in Prismic. Content managers will be able to add, edit, and remove categories from documents. They can also create and delete categories.
- Reuse your categories in multiple contexts. A list of links displayed on the blog page, for example, could be reused in posts with different styling.
- Add multiple categories to your documents. A blog post having multiple categories is a common strategy to group similar posts.
Prerequisites
To follow this tutorial, you should have: a Next.js project with Slice Machine, which has at least one page type and one page.
Don’t have a project? Launch our minimal starter to get started.
Define a “category” custom type
First, open Slice Machine, and create a reusable custom type called “Category”. Then, create a rich text field to store the category name.
- Static Zone
- UID
uid
UID - Name
name
Rich Text
Add a “categories” field to page types
In the page type you want to add a category to, create a repeatable group field. The repeatable group field will allow your content authors to select as many categories as they need.
- Static Zone
- UID
uid
UID - Categories
categories
Group- Category
category
Content Relationship
Next, create a content relationship field inside the repeatable group field, restricted to the category page type. The content relationship field will allow content authors to link to categories.
Create your first “category”
Open the Page Builder and create a categories document with the category name. Create a document for every category.
Add categories to pages
To add categories to your pages, select the relevant categories in the content relationship fields.
Define a category route
To create a route for the Categories custom type, add the following to the routes
array in prismicio.js
:
{
type: 'category',
path: '/categories/:uid',
}
Display a list of all categories
To create a list of every category, query by the category custom type.
client.getAllByType("category");
Then you can template the list of all categories to display on your page.
import { PrismicNextLink } from "@prismicio/next";
import { PrismicText } from "@prismicio/react";
import { createClient } from "@/prismicio";
export default async function Home() {
const client = createClient();
const categories = await client.getAllByType("category");
return (
<main>
<ul>
{categories.map((category) => {
return (
<li key={category.id}>
<PrismicNextLink document={category}>
<PrismicText field={category.data.name} />
</PrismicNextLink>
</li>
);
})}
</ul>
</main>
);
}
Display a page’s categories
To display a page’s categories, in page.js
, query the content relationship field in the page. Use fetchLinks
to fetch data in the linked categories. Then you can template the list of categories used in the page to display on the page.
import { PrismicNextLink } from "@prismicio/next";
import { PrismicText } from "@prismicio/react";
import { createClient } from "@/prismicio";
export default async function Post({ params }) {
const client = createClient();
const post = await client.getByUID("post", params.uid, {
fetchLinks: ["category.name"],
});
return (
<main>
<ul>
{post.data.categories.map((category) => {
return (
<li key={category.id}>
<PrismicNextLink document={category}>
<PrismicRichText
field={category.data.name}
/>
</PrismicNextLink>
</li>
);
})}
</ul>
</main>
);
}
export async function generateStaticParams() {
const client = createClient();
const posts = await client.getAllByType("post");
return posts.map((post) => {
return { uid: post.uid };
});
}
Display a list of pages in each category
To create a page for each category, in the app directory, create a file at app/category/[uid]/page.js
.
To create a list of pages in a category, in page.js
, retrieve the category ID for the category you wish to filter for by using client.getByUID()
.
Then query all documents with the page type you wish to display and use the at()
filter with the IDs of the page type, group field, content relationship, and category, like this:
prismic.filter.at('my.example_page_type.example_group.example_content_relationship', example_category_id).
Finally, you can template the list of pages with a specific category to display on your page.
import { PrismicNextLink } from "@prismicio/next";
import { createClient } from "@/prismicio";
import * as prismic from "@prismicio/client";
export default async function Category({ params }) {
const client = createClient();
// Query the specific category
const category = await client.getByUID(
"category",
params.uid,
);
// Use the category ID to filter for posts with that category
const pagesInCategory = await client.getAllByType(
"post",
{
filters: [
prismic.filter.at(
"my.post.categories.category",
category.id,
),
],
},
);
return (
<main>
<ul>
{pagesInCategory.map((page) => {
return (
<li key={pages.id}>
<PrismicNextLink document={page}>
{page.data.meta_title}
</PrismicNextLink>
</li>
);
})}
</ul>
</main>
);
}
export async function generateStaticParams() {
const client = createClient();
const categories = await client.getAllByType("category");
return categories.map((category) => {
return { uid: category.uid };
});
}
Going further
The taxonomy strategy shared in this article can be used as-is or as a base for your own custom taxonomy strategy.
Here are a few ideas you can try to customize your taxonomies:
- Create a page to list all of your categories
- Allow content managers to select an image for their categories and display them in the category list
- Support short descriptions for categories
- Create child categories
- Create an “author” type for your pages