These integration guides are not official documentation and the Strapi Support Team will not provide assistance with them.
What Is Stackbit?
Stackbit is a visual editing platform that works seamlessly with headless CMS systems like Strapi. By integrating Stackbit with Strapi, you create a powerful bridge between your developers and content creators, providing marketers with an intuitive "edit on the glass" experience while developers maintain their freedom to code as they prefer.
What makes Stackbit particularly valuable is how it integrates with your existing code through a simple config file. There's no need for additional dependencies. Your developers can keep using their preferred tech stack, and Stackbit remains separate from your website's production delivery, ensuring everything stays fast and reliable.
Why Integrate Stackbit with Strapi
Integrating Stackbit with Strapi creates a powerful composable Digital Experience Platform (DXP), blending developer flexibility with content creator usability. Strapi provides a robust backend system, while Stackbit offers an intuitive visual interface for streamlined content editing. This integration illustrates how a headless CMS and DXP can work together effectively.
Strapi’s flexibility and backend features make it an excellent choice for a headless CMS. This integration model can be extended to other systems, like integrating Saleor with Strapi, to build comprehensive eCommerce solutions.
This integration brings significant strategic advantages. Developers maintain full control over the backend architecture, data structures, and APIs, ensuring precision in coding. Simultaneously, marketers and content creators can quickly create, edit, preview, and publish content using Stackbit's visual tools.
The synergy between Strapi’s headless CMS and Stackbit’s visual editing tools bridges the gap between technical implementation and content management, streamlining workflows for both developers and content creators.
Integrating Stackbit with Strapi has specific advantages for development teams:
- Single file integration: Add Stackbit to Strapi with just one configuration file.
- No extra dependencies: Works without adding extra code packages.
- Preferred stack compatibility: Continue using your preferred development tools.
- Production independence: Stackbit stays separate from production, ensuring optimal CDN performance.
This integration also benefits content creators:
- Visual page assembly: Build and modify pages visually without requesting developer assistance, utilizing tools such as Strapi Dynamic Zone.
- Independent design control: Make design changes without developer help.
- Faster content creation: The visual interface accelerates content creation and publishing, especially with visual editing for Strapi.
By combining Strapi and Stackbit, teams can enjoy a more efficient, agile content management system that allows for independent work and faster response to market demands.
How to Integrate Stackbit with Strapi
Integrating Stackbit with Strapi creates a powerful combination that balances developer flexibility with content creator usability. In this guide, we'll cover the process of integrating Stackbit with Strapi, from initial setup to testing and validation.
Keep in touch with the latest Strapi and Stackbit updates
Prerequisites and System Requirements
Before you begin, ensure your system meets the following requirements:
- Operating System: Ubuntu 18.04+ (LTS), Debian 9.x+, CentOS/RHEL 8+, macOS Mojave+, or Windows 10
- Node.js: LTS versions (v12 or v14)
- NPM: v6 or the version bundled with LTS Node
- Hardware: Minimum 1 core CPU (2 cores recommended), 2GB RAM (4GB recommended), and 32GB free storage
- Standard build tools for your operating system
Setting Up Strapi
1. To start a new Strapi project, use the following command for the recommended local installation:
1npx create-strapi@latest
2. Create a new Strapi project:
1strapi new my-project
3. Navigate to your project directory and start Strapi:
1cd my-project
2yarn develop
1cd my-project
2npm run develop
4. Access the Strapi admin panel at http://localhost:1337/admin and create your first admin account.
5. Set up your content types using the Strapi Content Types Builder in the Strapi admin panel. For a deeper understanding of content modeling in Strapi, you can consult this guide.
To manage your configurations efficiently across environments, consider using the Strapi Config Sync Plugin.
Connecting Strapi with Stackbit
Let's walk through how to integrate Stackbit with Strapi:
- Create a Stackbit configuration file in your code repository that defines how Stackbit communicates with your Strapi content.
- Set up authentication:
- Create API tokens in Strapi (Settings → API Tokens).
- Configure these tokens in your Stackbit configuration.
- Set appropriate permissions for content types that will be edited via Stackbit.
- Map your components to Strapi content types in the Stackbit configuration to enable visual editing.
Understanding the differences between traditional vs. headless CMS options will help you appreciate the flexibility offered by this integration.
Local Development and Testing
To set up a local development environment:
- Import your repository to Stackbit.
- Use Stackbit's development container for your project.
- Start local development with:
1stackbit dev
This allows you to see how your Strapi content appears in the Stackbit visual editor while developing.
Production Deployment
When you're ready to deploy:
- Deploy your Strapi instance to your chosen hosting platform.
- Deploy your front-end application.
- Configure Stackbit settings to point to the production Strapi API.
- Ensure proper environment variables for API connections.
For continuous integration:
- Set up GitHub workflows or other CI pipelines.
- Configure deployment to trigger content or code changes.
- Securely manage API tokens in your CI/CD environment.
\
Keep in touch with the latest Strapi and Stackbit updates
Project Example (+ GitHub Project Repo)
When you integrate Stackbit with Strapi, it's helpful to see a real-world implementation. Let's explore a practical example that demonstrates how these platforms work together to create a powerful web development ecosystem.
Implementation Highlights
Our example project showcases a marketing website for a SaaS company. The backend is built with Strapi, handling product information, pricing details, and blog content. Stackbit provides the visual editing layer, allowing marketers to create and modify landing pages without developer intervention.
Key implementation details include:
- Content Model Structure: In Strapi, we've defined content types for products, pricing plans, blog posts, and reusable components like hero sections and feature blocks.
- Component Setup: We've created a set of flexible components in our front-end framework, each mapped to corresponding Strapi content types. This mapping is defined in the Stackbit configuration file, enabling visual editing of specific components directly through Stackbit.
- API Configuration: We've set up custom API endpoints in Strapi to deliver optimized content payloads for different page types. These endpoints are consumed by our front-end application and integrated with Stackbit for seamless content updates.
- Authentication: We've implemented secure authentication between Stackbit and Strapi using API tokens, ensuring that only authorized users can make content changes.
Example Code
Here's how the integration looks in the code. First, let's examine the Stackbit configuration file (stackbit.config.js
) that connects our Next.js front-end with Strapi:
1// stackbit.config.js
2module.exports = {
3 stackbitVersion: '~0.6.0',
4 ssgName: 'nextjs',
5 cmsName: 'strapi',
6 nodeVersion: '16',
7
8 // Strapi-specific configuration
9 strapiConfig: {
10 baseUrl: process.env.STRAPI_API_URL || 'http://localhost:1337',
11 accessToken: process.env.STRAPI_API_TOKEN,
12 },
13
14 // Content model definitions
15 models: {
16 page: {
17 type: 'page',
18 urlPath: '/{slug}',
19 modelName: 'page',
20 strapiCollection: 'pages',
21 fields: [
22 { name: 'title', type: 'string', required: true },
23 { name: 'slug', type: 'string', required: true },
24 {
25 name: 'sections',
26 type: 'list',
27 items: { type: 'model', models: ['hero', 'features', 'pricing'] }
28 },
29 { name: 'seo', type: 'model', models: ['seo'] }
30 ]
31 },
32 hero: {
33 type: 'object',
34 label: 'Hero Section',
35 strapiComponent: 'sections.hero',
36 fields: [
37 { name: 'heading', type: 'string' },
38 { name: 'subheading', type: 'string' },
39 { name: 'image', type: 'image' },
40 {
41 name: 'buttons',
42 type: 'list',
43 items: { type: 'model', models: ['button'] }
44 }
45 ]
46 },
47 // More model definitions...
48 }
49};
Next, here's an example of a Strapi content type definition (api/page/content-types/page/schema.json
):
1{
2 "kind": "collectionType",
3 "collectionName": "pages",
4 "info": {
5 "singularName": "page",
6 "pluralName": "pages",
7 "displayName": "Page",
8 "description": "Create and manage dynamic pages"
9 },
10 "options": {
11 "draftAndPublish": true
12 },
13 "pluginOptions": {},
14 "attributes": {
15 "title": {
16 "type": "string",
17 "required": true
18 },
19 "slug": {
20 "type": "uid",
21 "targetField": "title",
22 "required": true
23 },
24 "sections": {
25 "type": "dynamiczone",
26 "components": [
27 "sections.hero",
28 "sections.features",
29 "sections.pricing"
30 ]
31 },
32 "seo": {
33 "type": "component",
34 "component": "shared.seo"
35 }
36 }
37}
Here's a React component for rendering a Hero section from Strapi data, with Stackbit annotations for visual editing:
1// components/sections/Hero.jsx
2import React from 'react';
3import { sbEditable } from '@stackbit/annotations';
4
5const Hero = ({ section }) => {
6 if (!section) return null;
7
8 const { heading, subheading, image, buttons } = section;
9
10 return (
11 <section {...sbEditable(section)} className="hero-section">
12 <div className="container">
13 <div className="hero-content">
14 <h1 className="hero-heading">{heading}</h1>
15 <p className="hero-subheading">{subheading}</p>
16
17 {buttons && buttons.length > 0 && (
18 <div className="hero-buttons">
19 {buttons.map((button, index) => (
20 <a
21 key={index}
22 href={button.url}
23 className={`btn ${button.style || 'primary'}`}
24 {...sbEditable(button)}
25 >
26 {button.label}
27 </a>
28 ))}
29 </div>
30 )}
31 </div>
32
33 {image && (
34 <div className="hero-image">
35 <img
36 src={image.url}
37 alt={image.alternativeText || heading}
38 width={image.width}
39 height={image.height}
40 />
41 </div>
42 )}
43 </div>
44 </section>
45 );
46};
47
48export default Hero;
For API communication with Strapi, here's an example utility function for fetching data:
1// lib/strapi.js
2import qs from 'qs';
3
4/**
5 * Get full Strapi URL from path
6 * @param {string} path Path of the URL
7 * @returns {string} Full Strapi URL
8 */
9export function getStrapiURL(path = '') {
10 return `${
11 process.env.NEXT_PUBLIC_STRAPI_API_URL || 'http://localhost:1337'
12 }${path}`;
13}
14
15/**
16 * Helper to make GET requests to Strapi API endpoints
17 * @param {string} path Path of the API route
18 * @param {Object} urlParamsObject URL params object, will be stringified
19 * @param {Object} options Options passed to fetch
20 * @returns Parsed API call response
21 */
22export async function fetchAPI(path, urlParamsObject = {}, options = {}) {
23 // Merge default and user options
24 const mergedOptions = {
25 headers: {
26 'Content-Type': 'application/json',
27 'Authorization': `Bearer ${process.env.STRAPI_API_TOKEN}`
28 },
29 ...options,
30 };
31
32 // Build request URL
33 const queryString = qs.stringify(urlParamsObject);
34 const requestUrl = `${getStrapiURL(
35 `/api${path}${queryString ? `?${queryString}` : ''}`
36 )}`;
37
38 // Trigger API call
39 const response = await fetch(requestUrl, mergedOptions);
40
41 // Handle response
42 if (!response.ok) {
43 console.error(response.statusText);
44 throw new Error(`An error occurred please try again`);
45 }
46
47 const data = await response.json();
48 return data;
49}
50
51/**
52 * Fetch a specific page with all its sections
53 * @param {string} slug Page slug
54 * @returns {Object} Page data including all sections
55 */
56export async function getPageBySlug(slug) {
57 const data = await fetchAPI('/pages', {
58 filters: { slug },
59 populate: {
60 sections: {
61 populate: '*',
62 },
63 seo: {
64 populate: '*',
65 },
66 },
67 });
68
69 return data?.data?.[0] || null;
70}
The full project code is available in this GitHub repository: github.com/example/strapi-stackbit-demo
Strapi Open Office Hours
If you have any questions about Strapi 5 or just would like to stop by and say hi, you can join us at Strapi's Discord Open Office Hours, Monday through Friday, from 12:30 pm to 1:30 pm CST: Strapi Discord Open Office Hours.
For more details, visit the Strapi documentation and the Stackbit documentation.
FAQ
What are the key benefits of integrating Stackbit with Strapi?
Integrating Stackbit with Strapi combines Strapi's powerful backend capabilities with Stackbit's intuitive visual interface. This synergy offers advantages like visual "on-the-glass" editing, seamless integration with existing codebases, direct CMS API interaction, and flexible local development and deployment options.
How do I set up Stackbit with Strapi?
To set up Stackbit with Strapi, start by creating a Stackbit configuration file in your code repository. Then, set up authentication by creating API tokens in Strapi and configuring these in your Stackbit setup. Finally, map your components to Strapi content types in the Stackbit configuration to enable visual editing.
Are there any prerequisites for integrating Stackbit with Strapi?
Yes, the prerequisites include having an operating system like Ubuntu 18.04+ (LTS), Debian 9.x+, CentOS/RHEL 8+, macOS Mojave+, or Windows 10, Node.js LTS versions (v12 or v14), NPM (v6 or the version bundled with LTS Node), and standard build tools for your operating system.
What support resources are available for developers working with Stackbit and Strapi?
Developers can access support resources like Strapi Open Office Hours, community forums, comprehensive documentation from both Strapi and Stackbit, GitHub repositories for community-driven support, and video tutorials, including webinars demonstrating practical workflows.
How can I optimize the performance of my Strapi and Stackbit integration?
To optimize performance, consider implementing caching strategies, using incremental builds to minimize build times, optimizing API calls for efficiency, and creating component presets in Stackbit for quick page assembly.
What common challenges might I face when integrating Stackbit with Strapi, and how can I address them?
Common challenges include content synchronization issues, localization complexities, performance optimization, scalability concerns, and data persistence. Address these challenges by implementing version control, phasing in languages for localization, setting up efficient caching and API calls, assessing project requirements for scalability, and adding validation layers for data persistence.