Developers
This guide covers advanced patterns for fetching content from Agility CMS, including filtering, sorting, pagination, and nested content.
This guide covers advanced patterns for fetching content from Agility CMS, including filtering, sorting, pagination, and nested content.
import { getContentItem } from "@/lib/cms/getContentItem"
const { fields, contentID } = await getContentItem<IPost>({
contentID: 204,
languageCode: "en-us"
})
import { getContentList } from "@/lib/cms/getContentList"
const { items, totalCount } = await getContentList<IPost>({
referenceName: "posts",
languageCode: "en-us"
})
const { items } = await getContentList<IPost>({
referenceName: "posts",
languageCode: "en-us",
filter: "fields.categoryID:eq:5"
})
eq: Equalsne: Not equalsgt: Greater thangte: Greater than or equallt: Less thanlte: Less than or equalin: In arraycontains: Contains stringfilter: "fields.categoryID:eq:5:and:fields.published:eq:true"
const { items } = await getContentList<IPost>({
referenceName: "posts",
languageCode: "en-us",
sort: "fields.postDate:desc"
})
asc: Ascendingdesc: Descendingsort: "fields.categoryID:asc,fields.postDate:desc"
const { items, totalCount } = await getContentList<IPost>({
referenceName: "posts",
languageCode: "en-us",
take: 10,
skip: 0
})
const pageSize = 10
const currentPage = 1
const skip = (currentPage - 1) * pageSize
const { items, totalCount } = await getContentList<IPost>({
referenceName: "posts",
languageCode: "en-us",
take: pageSize,
skip
})
const totalPages = Math.ceil(totalCount / pageSize)
Grid/link fields require separate fetching:
// 1. Get parent with nested reference
const { fields: { bentoCards: { referencename } } } =
await getContentItem<IBentoSection>({
contentID: module.contentid,
languageCode,
})
// 2. Fetch nested collection
const bentoCards = await getContentList<IBentoCard>({
referenceName: referencename, // Use referencename
languageCode,
take: 20
})
Linked content fields are auto-populated by the SDK:
const { fields } = await getContentItem<IPost>({
contentID: 204,
languageCode: "en-us"
})
// Author is automatically populated
const authorName = fields.author.fields.name
Use contentLinkDepth to control how deeply linked content is populated:
// API call with depth
const response = await fetch(
`https://api.aglty.io/${guid}/fetch/en-us/item/204?contentLinkDepth=2`,
{ headers: { APIKey: key } }
)
The SDK automatically handles depth based on field types:
const [page, posts, settings] = await Promise.all([
getAgilityPage({ slug: ["home"], languageCode: "en-us" }),
getContentList<IPost>({ referenceName: "posts", languageCode: "en-us" }),
getContentItem<IGlobalSettings>({ contentID: 1, languageCode: "en-us" })
])
try {
const { fields } = await getContentItem<IPost>({
contentID: 999,
languageCode: "en-us"
})
} catch (error) {
if (error.status === 404) {
// Handle not found
return <div>Post not found</div>
}
throw error
}
const { fields } = await getContentItem<IPost>({
contentID: 204,
languageCode: "en-us"
}).catch(() => ({
fields: {
heading: "Default Heading",
content: "Default content"
}
}))
Always limit large lists:
const { items } = await getContentList<IPost>({
referenceName: "posts",
languageCode: "en-us",
take: 10 // Limit results
})
Leverage built-in caching:
// Caching is automatic with getContentItem/getContentList
// Cache tags: agility-content-{id}-{locale}
// Revalidation: 60 seconds default
Use parallel fetching when possible:
// ✅ Parallel (faster)
const [item1, item2] = await Promise.all([
getContentItem({ contentID: 1, languageCode: "en-us" }),
getContentItem({ contentID: 2, languageCode: "en-us" })
])
// ❌ Sequential (slower)
const item1 = await getContentItem({ contentID: 1, languageCode: "en-us" })
const item2 = await getContentItem({ contentID: 2, languageCode: "en-us" })
Next: Caching - Caching strategies