Taxonomies
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.
Other taxonomies
In this how-to, we use the example of a category to demonstrate how to create a taxonomy. You can use the same general principles to create other taxonomies, like authors, sections, tags, topics, genres, tiers, or promotions.
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.
First, open Slice Machine, and create a reusable custom type called “Category”. Then, create a rich text field to store the category name.
- UIDuidUID
- NamenameRich Text
Copy{
"id": "category",
"label": "Category",
"format": "custom",
"repeatable": true,
"status": true,
"json": {
"Main": {
"uid": {
"config": {
"label": "UID"
},
"type": "UID"
},
"name": {
"type": "StructuredText",
"config": {
"label": "Name",
"placeholder": "",
"allowTargetBlank": true,
"single": "paragraph,heading1,heading2,heading3"
}
}
}
}
}
In the page type you want to add a category to, create a group field. The group field will allow your content authors to select as many categories as they need.
- UIDuidUID
- CategoriescategoriesGroup
- CategorycategoryContent Relationship
- Meta Titlemeta_titleA title of the page used for social media and search enginesKey Text
Copy{
"id": "post",
"label": "Post",
"format": "page",
"repeatable": true,
"status": true,
"json": {
"Main": {
"uid": {
"config": {
"label": "UID"
},
"type": "UID"
},
"categories": {
"type": "Group",
"config": {
"label": "Categories",
"fields": {
"category": {
"type": "Link",
"config": {
"label": "Category",
"select": "document",
"customtypes": [
"category"
]
}
}
}
}
},
"slices": {
"type": "Slices",
"fieldset": "Slice Zone",
"config": {
"choices": {}
}
}
},
"SEO & Metadata": {
"meta_title": {
"config": {
"label": "Meta Title",
"placeholder": "A title of the page used for social media and search engines"
},
"type": "Text"
}
}
}
}
Next, create a content relationship field inside the group field, restricted to the category page type. The content relationship field will allow content authors to link to categories.
Open the Page Builder and create a categories document with the category name. Create a document for every category.
To add categories to your pages, select the relevant categories in the content relationship fields.
To create a route for the Categories custom type, add the following to the routes
array in prismicio.js
:
{
type: 'category',
path: '/categories/:uid',
}
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>
)
}
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 }
})
}
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 }
})
}
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
Was this article helpful?
Can't find what you're looking for? Spot an error in the documentation? Get in touch with us on our Community Forum or using the feedback form above.