
Strapi REST API does not automatically return relations, media, components, and dynamic zones. You must declare what to populate. populate=* is useful for local exploration, but production pages should request precise fields and relations.
This guide focuses on Strapi 5. Strapi 4 response shapes and some behaviors differ, so confirm your project version before copying code.
Example content model
Assume Article has:
title,slug, andexcerptcovermediaauthorrelationcategoryrelationcommentsrelationseocomponent
A plain request:
GET /api/articles
returns article fields, but does not recursively expand all relations. This prevents accidental loading of the whole content graph.
populate=*
GET /api/articles?populate=*
This is fine for debugging or simple previews. It does not mean "load infinite depth." As the content model grows, wildcard population can make responses much larger and slower.
Populate only what you need
For cover and author:
GET /api/articles?populate[cover]=true&populate[author]=true
Limit main fields too:
GET /api/articles?fields[0]=title&fields[1]=slug&fields[2]=excerpt&populate[cover]=true&populate[author]=true
Use fields for ordinary fields. Use populate for relations, media, components, and dynamic zones.
Select fields inside populated data
If the author only needs a name and the cover only needs URL and alt text:
GET /api/articles?populate[author][fields][0]=name&populate[cover][fields][0]=url&populate[cover][fields][1]=alternativeText
Field selection reduces response size and accidental exposure. It is not a replacement for permissions. Real access control belongs in roles, API tokens, policies, and controllers.
Nested populate
For comments and each comment's author:
GET /api/articles?populate[comments][populate][author][fields][0]=name
You can also select and sort comment fields:
GET /api/articles?populate[comments][fields][0]=content&populate[comments][sort][0]=createdAt:desc&populate[comments][populate][author][fields][0]=name
Nested queries can become expensive quickly. If a page only shows a comment count, do not load all comments and authors just to compute that number.
Use qs for complex queries
Bracket URLs are easy to mistype. Use qs:
import qs from "qs"
const query = qs.stringify(
{
fields: ["title", "slug", "excerpt"],
populate: {
cover: { fields: ["url", "alternativeText"] },
author: { fields: ["name"] },
comments: {
fields: ["content", "createdAt"],
sort: ["createdAt:desc"],
populate: {
author: { fields: ["name"] },
},
},
},
},
{ encodeValuesOnly: true },
)
const response = await fetch(`${STRAPI_URL}/api/articles?${query}`)
Keep query objects in a data access layer, not copied across many React components.
Next.js fetch wrapper
type Article = {
documentId: string
title: string
slug: string
excerpt: string
cover?: { url: string; alternativeText?: string }
author?: { name: string }
}
export async function getArticles(): Promise<Article[]> {
const response = await fetch(`${process.env.STRAPI_URL}/api/articles?${query}`, {
next: { revalidate: 300 },
})
if (!response.ok) {
throw new Error(`Strapi request failed: ${response.status}`)
}
const payload = await response.json()
return payload.data
}
If code still reads data.attributes, verify whether it was written for Strapi 4.
Common problems
If populate returns empty data, check:
- Related content is published.
- Public role or API token has read permission for the target type.
- Field names match the Content-Type Builder.
- Locale, publication state, or filters are not excluding the content.
- Front-end code reads the Strapi 5 response shape correctly.
If responses are too slow or too large:
- Replace
populate=*with explicit fields. - Avoid loading body, comments, and authors on list pages.
- Add pagination.
- Split complex pages into separate queries.
- Consider page-specific custom controllers.
Related FreeMac guides
- For the Next.js integration, read Next.js with Strapi 5: Fetching, Cache, and Security.
- For Next.js data boundaries, read Next.js Server vs Client Components.
- If you still need the content modeling intro, the Chinese version is available at Strapi 5 入门.
Continue reading
Strapi 5 Getting Started: Content Models, APIs, and Permissions
Start a Strapi 5 project, choose between Collection Types, Single Types, Components, and Dynamic Zones, then publish content and verify REST API permissions.
12 min readNext.js with Strapi 5: Fetching, Cache, and Security
Connect Next.js App Router to Strapi 5 safely with server-side fetch helpers, populate queries, cache rules, draft preview boundaries, media URLs, and private API tokens.
7 min readNestJS Decorators: Class, Method, and Parameter Decorators
Understand NestJS decorators by separating class decorators like Controller and Injectable, method decorators like Get and Post, and parameter decorators like Body, Param, and Query.
Subscribe to FreeMac
Weekly picks: free Mac software reviews, trusted source updates, alternatives, and low-friction guides.