Strapi Components & Dynamic Zones — Reusable Field Groups and Flexible Layouts
In this tutorial, you will learn how to create reusable field groups using Strapi components and build flexible page layouts with dynamic zones, giving you the power to model complex, structured content for modern frontends.
What You'll Learn
- What components are and how they differ from content types
- How to create single and repeatable components
- The difference between components and dynamic zones
- How to build dynamic zones for flexible page Builder experiences
- How components and dynamic zones appear in the API response
- Best practices for organizing and naming components
Why It Matters
Real-world content is rarely flat. A blog post might have a hero image, a text section, a call-to-action block, a related posts section, and an author bio. Each section has different fields. Dynamic zones let editors mix and match these sections in any order. Components share common field groups across types. Together, they enable the kind of structured content that modern frontends expect.
Real-World Use
A marketing team needs to build landing pages with sections like Hero (headline, subhead, background image, CTA button), Features (grid of feature cards with icon, title, description), Testimonials (carousel of quotes with author photo), and FAQ (accordion of questions and answers). Each section is a component in a dynamic zone on the Page content type. The marketing team can create any page layout without developer assistance.
Learning Path
flowchart LR A["Content Types"] --> B["Fields"] B --> C["Relations"] C --> D["Components & Dynamic Zones
-- You are here"]:::current D --> E["Content Lifecycle"] E --> F["REST API"] classDef current fill:#4945ff,color:#fff,stroke-width:2px
What are Components?
Components are reusable groups of fields. You define the fields once and can add the component to any content type or another component.
Think of components like building blocks. An "Address" component has street, city, and zip fields. Instead of defining these three fields on every content type that needs an address (User, Restaurant, Office), you create the component once and reuse it everywhere.
Components differ from content types in a critical way: components have no independent existence. They cannot be queried independently through the API. They only exist as part of a content type that includes them.
Creating Components
In the Content-Type Builder, click "Create a new component." You need to provide:
- Name: The display name (e.g., "SEO", "Address", "Social Link")
- Category: A grouping category (e.g., "common", "seo", "layout")
- Icon: An icon from the available set
// Component structure in the filesystem
// src/components/common/seo.json
{
"collectionName": "components_common_seos",
"info": {
"displayName": "SEO",
"icon": "search",
"description": "SEO metadata fields"
},
"attributes": {
"meta_title": {
"type": "string",
"required": true,
"maxLength": 60
},
"meta_description": {
"type": "text",
"required": true,
"maxLength": 160
},
"og_image": {
"type": "media",
"allowedTypes": ["images"],
"multiple": false
}
}
}
After creating the component, you add it as a field to any content type. The component appears as a single field group in the entry editor.
Single vs Repeatable Components
Components can be added as single (not repeatable) or repeatable.
A single component means one instance. For example, an Article has one SEO component. There is one meta title, one meta description, and one OG image.
A repeatable component means the editor can add multiple instances. For example, an Article has a "Related Links" repeatable component. The editor can add 0, 3, or 10 links, each with its own title and URL.
// In the API response:
// Single component
"seo": {
"id": 1,
"meta_title": "Best Pizza Recipes",
"meta_description": "Discover our collection..."
}
// Repeatable component
"related_links": [
{
"id": 1,
"title": "Pasta Recipes",
"url": "/pasta"
},
{
"id": 2,
"title": "Dessert Recipes",
"url": "/dessert"
}
]
Dynamic Zones
Dynamic zones are the most flexible content modeling tool in Strapi. A dynamic zone lets editors choose from a set of components and arrange them in any order.
Create a dynamic zone on a content type by selecting "Dynamic Zone" from the field types. Then add components to the zone. Editors using the Content Manager can add, remove, reorder, and configure each component instance.
For example, a "Page" content type might have a dynamic zone called "Sections" containing:
- Hero Section (headline, subhead, background_image, cta_text, cta_url)
- Feature Grid (features as a repeatable component with icon, title, description)
- Testimonial Carousel (testimonials as a repeatable component with quote, author_name, author_photo)
- FAQ Accordion (questions as a repeatable component with question, answer)
- Call to Action (headline, button_text, button_url, background_color)
// API response for a page with a dynamic zone
"dynamic_sections": [
{
"__component": "sections.hero",
"id": 1,
"headline": "Welcome to Our Site",
"subhead": "Discover amazing content",
"background_image": {...}
},
{
"__component": "sections.feature-grid",
"id": 2,
"features": [
{
"id": 1,
"icon": "star",
"title": "Feature 1",
"description": "Description 1"
},
{
"id": 2,
"icon": "heart",
"title": "Feature 2",
"description": "Description 2"
}
]
},
{
"__component": "sections.faq-accordion",
"id": 3,
"items": [
{
"id": 1,
"question": "What is this?",
"answer": "A dynamic zone example"
}
]
}
]
Each item in a dynamic zone includes a __component field that tells the frontend which component type it is. Your frontend uses this to render the appropriate component.
When to Use Components vs Dynamic Zones
| Scenario | Use |
|---|---|
| Reusable fields across types | Component |
| Fixed structure within a content type | Component (single or repeatable) |
| Editor-controlled layout | Dynamic Zone |
| Multiple section types in flexible order | Dynamic Zone |
| Structured data like SEO metadata | Component |
| Page building like landing pages | Dynamic Zone |
You might be wondering when to use a repeatable component vs a dynamic zone. If the content type has a fixed structure but repeatable items (like a gallery of images), use a repeatable component. If the editor should choose from different section types and arrange them freely, use a dynamic zone.
Nested Components
Components can contain other components. This is useful for building complex, structured content.
// sections.hero component with a nested CTA component
// sections/hero.json
{
"attributes": {
"headline": { "type": "string" },
"background": { "type": "media" },
"cta": {
"type": "component",
"repeatable": false,
"component": "common.cta-button"
}
}
}
// common/cta-button.json
{
"attributes": {
"text": { "type": "string" },
"url": { "type": "string" },
"variant": { "type": "enumeration", "enum": ["primary", "secondary", "outline"] }
}
}
The maximum nesting depth is limited by practical considerations. Deeply nested components become difficult to manage in the admin panel editor.
Best Practices
Organize components by category. Create categories like "common" (reusable across types), "sections" (landing page sections), "media" (media-related groups), and "seo" (metadata). This keeps the component list manageable.
Keep components focused. A component should do one thing well. A "Hero Section" component for a dynamic zone is fine. A "Everything Section" component with 30 optional fields defeats the purpose.
Design components for your frontend. Think about how your frontend will render each component. The
__componentfield drives conditional rendering. Each component should map to one frontend component.Avoid deep nesting in dynamic zones. Deeply nested dynamic zones are hard to edit in the admin panel and complex to render on the frontend. Keep dynamic zone items flat with one level of nested components.
Test component layouts in the admin panel. Create a test entry and experiment with adding, removing, and reordering dynamic zone items. The editor experience matters for your content team.
Common Mistakes
Using a component where a content type is needed. If you need to query data independently or it has its own API endpoint, use a content type, not a component. Components cannot be queried independently.
Creating too many components in a dynamic zone. A dynamic zone with 20 different component types overwhelms editors. Limit dynamic zones to 5-10 well-designed component types.
Not providing sensible defaults. Components with no default values force editors to fill every field. Set meaningful defaults where possible to speed up content creation.
Ignoring the admin panel UX. A component with 15 fields is a poor editing experience. Consider breaking it into smaller components or using tabs and collapsible groups.
Forgetting to update the frontend when adding new components to a dynamic zone. Adding a new component type to a dynamic zone breaks any frontend that does not handle it. Always coordinate component additions with frontend updates.
Practice Questions
What is the difference between a component and a content type? Answer: Components are reusable field groups that only exist within a parent content type. They cannot be queried independently and have no API endpoints. Content types have their own database tables and API endpoints.
When would you use a dynamic zone instead of a repeatable component? Answer: When the editor should choose from different types of sections (hero, features, FAQ) and arrange them in any order. Dynamic zones allow mixing different component types in a single list.
How does the API identify which component type each item in a dynamic zone is? Answer: Each dynamic zone item includes a
__componentfield with the component identifier (e.g., "sections.hero"). The frontend uses this to render the correct component.Challenge: Create a complete landing page builder with a dynamic zone containing at least 6 different section types: Hero (headline, subhead, CTA button, background image), Features Grid (repeatable feature cards), Testimonials (repeatable testimonial cards), FAQ (repeatable Q&A items), Pricing Table (plan name, price, features list), and Newsletter Signup (headline, placeholder text, button text). Build a page with all sections in a meaningful order.
FAQ
Mini Project
Your task: Build a modular page system with components and dynamic zones.
- Create these components in a "sections" category:
- Hero: headline (string), subhead (text), cta_text (string), cta_url (string), background (media, image)
- Feature Card: icon (string), title (string), description (richtext)
- Features Grid: features (repeatable Feature Card component)
- Testimonial: quote (richtext), author_name (string), author_title (string), avatar (media, image)
- Testimonials: items (repeatable Testimonial component)
- FAQ Item: question (string), answer (richtext)
- FAQ: items (repeatable FAQ Item component)
- Create a "Page" collection type with title (string), slug (UID from title), and a dynamic zone "sections" containing all the above components.
- Create 3 pages with different section combinations and orderings.
- Test the API and verify that the
__componentfield correctly identifies each section type.
What's Next
Now that you understand components and dynamic zones, proceed to Content Lifecycle to learn about draft/publish workflow, versioning, and content scheduling. After that, dive into the REST API to consume your content programmatically.
Related lessons:
- REST API — Consuming content with dynamic zones
- GraphQL — Querying dynamic zones with Graphql
- WordPress Gutenberg Blocks — Compare with dynamic zones
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro