These integration guides are not official documentation and the Strapi Support Team will not provide assistance with them.
What Is Astro?
Astro is a modern, open-source web framework designed for building fast, content-driven websites such as blogs, marketing pages, and e-commerce platforms.
Its standout “islands architecture” serves static HTML by default and only loads JavaScript for interactive components, delivering exceptionally fast load times and an improved user experience compared to traditional JavaScript-heavy frameworks.
Astro also lets developers use UI libraries like React, Vue, and Svelte within a single project, offering both flexibility and ease of integration.
With built-in performance optimizations-including automatic code-splitting, asset optimization, and static site generation-Astro is ideal for content-rich sites where speed and SEO are critical. Its architecture is especially powerful when paired with a headless CMS like Strapi, enabling teams to manage content flexibly while delivering lightning-fast, modern web experiences.
Why Use Strapi with Astro
Combining Strapi, a powerful, customizable headless CMS, with Astro, a modern static site generator (SSG), creates a robust solution for building fast, flexible, and scalable websites.
This Astro and Strapi integration leverages the strengths of both platforms for an outstanding developer and user experience.
More specifically, here are some key benefits:
- Separation of concerns: Strapi manages content with a user-friendly interface, while Astro generates optimized static pages, allowing teams to work independently.
- Exceptional performance: Strapi’s flexible API and Astro’s static site generation minimize JavaScript and maximize speed and SEO.
- Great developer experience: Content creators use Strapi’s intuitive UI, while developers leverage their preferred frontend tools in Astro for rapid development and easy maintenance, highlighted in.
- API flexibility: Strapi offers both REST and GraphQL endpoints, enabling flexible and efficient data fetching in Astro projects.
- Scalability: The decoupled architecture allows Strapi and Astro to scale independently as content or traffic grows.
- Workflow improvements: Research shows integrating static site generators with headless CMS platforms like Strapi streamlines workflows and boosts performance.
- Continuous advancements: Strapi Cloud provides managed CMS hosting, and Strapi v5 brings further performance and developer experience improvements.
If you’re interested in this combination, check out the Strapi documentation for Astro integration or try a demo to see how Strapi and Astro can transform your workflow.
Keep in touch with the latest Strapi and Astro updates
Getting Started with Astro and Strapi
Integrating Astro with Strapi lets you build fast, content-driven websites powered by a flexible headless CMS backend. Here’s a step-by-step guide to setting up and connecting these tools for a modern web project.
Prerequisites
- Node.js (latest LTS version recommended)
- Basic knowledge of JavaScript and APIs
- Familiarity with content management systems
Setting up Strapi
- Initialize a new Strapi project:
1npx create-strapi-app my-project --quickstart
- Once Strapi is running, access the admin panel (typically at
http://localhost:1337/admin
) to create content types and configure API permissions. - Set up at least one content type (e.g., “Article” or “Post”) and add sample content.
Setting up Astro
- Create a new Astro project:
1npm create astro@latest
- Follow the prompts to complete setup. For more detail, see the Astro & Strapi tutorial.
- Install the Strapi integration:
1npm install @astrojs/strapi
- Optimize your Strapi backend for best performance. See performance tips.
Connecting Astro to Strapi
- Store your Strapi API URL in Astro’s
.env
file:1STRAPI_URL=http://localhost:1337
Create a data-fetching utility in Astro (e.g.,
src/lib/strapi.js
):1const strapiUrl = import.meta.env.STRAPI_URL; 2 3export async function fetchPosts() { 4 const response = await fetch(`${strapiUrl}/api/posts?populate=*`); 5 const { data } = await response.json(); 6 return data; 7}
Fetch content in your Astro component or page:
1--- 2import { fetchPosts } from '../lib/strapi'; 3 4const posts = await fetchPosts(); 5--- 6 7<ul> 8 {posts.map((post) => ( 9 <li>{post.attributes.title}</li> 10 ))} 11</ul>
As the Astro CMS guide notes, always use environment variables for API URLs and access tokens-never hard-code secrets.
Content Modeling in Strapi
- Use collection types for repeatable content (e.g., blog posts, products)
- Use single types for unique pages (e.g., homepage, about)
- Set up relationships between content types (e.g., authors to posts)
- Configure media fields for assets
- Use modular components (blocks, authors, featured sections) to empower editors and maintain layout consistency
Fetching Content in Astro
Astro supports several strategies for consuming Strapi content:
- Static Site Generation (SSG):
1export async function getStaticPaths() { 2 const posts = await fetchPosts(); 3 return posts.map((post) => ({ 4 params: { slug: post.attributes.slug }, 5 props: { post }, 6 })); 7}
- Server-Side Rendering (SSR):
1export async function get({ params }) { 2 const post = await fetchPostBySlug(params.slug); 3 return { 4 body: JSON.stringify(post), 5 }; 6}
Client-side fetching (for interactive components):
1import { useState, useEffect } from 'react'; 2 3function LatestPosts() { 4 const [posts, setPosts] = useState([]); 5 6 useEffect(() => { 7 fetchPosts().then(setPosts); 8 }, []); 9 10 return ( 11 <ul> 12 {posts.map((post) => ( 13 <li key={post.id}>{post.attributes.title}</li> 14 ))} 15 </ul> 16 ); 17}
For multilingual content, use Astro’s data-fetching logic to select the correct locale for each page.
Managing Dynamic Content Updates
- Set up webhooks in Strapi to trigger Astro rebuilds when content changes.
- Implement incremental builds to reduce build times.
- Create preview environments for editors to review changes before publishing.
When an editor publishes or updates content in Strapi, a webhook can automatically trigger a new Astro build and deployment on platforms like Vercel or Netlify.
By following these steps and best practices, you’ll have a solid foundation for integrating Astro and Strapi-enabling flexible content management and delivering high-performance websites for modern web projects.
Keep in touch with the latest Strapi and Astro updates
Project Example (+ Github Project Repo)
Let's walk through building a practical example project that integrates Astro with Strapi-a simple but powerful blog site. For a complete working reference, see PaulBratslavsky/strapi-astro-blog-post on GitHub18.
Project Overview
Our blog will feature:
- A homepage displaying recent articles
- Individual article pages
- Author profiles
- Category filtering
Strapi Setup
- Initialize a new Strapi project:
1npx create-strapi-app@latest my-blog-backend
- Create the following content types in Strapi:
- Article (Collection Type)
- Title (Text)
- Content (Rich Text)
- Slug (UID)
- Featured Image (Media)
- Author (Relation to Author)
- Categories (Relation to Category)
- Author (Collection Type)
- Name (Text)
- Bio (Rich Text)
- Avatar (Media)
- Category (Collection Type)
- Name (Text)
- Description (Text)
- Article (Collection Type)
- Set up roles and permissions to allow public access to your content types.
Astro Implementation
- Create a new Astro project:
1npm create astro@latest my-blog-frontend
- Install necessary dependencies:
1npm install axios
- Create a
.env
file in your Astro project root:1STRAPI_URL=http://localhost:1337
Create a utility file
src/lib/strapi.js
for API calls:1import axios from 'axios'; 2 3const strapiUrl = import.meta.env.STRAPI_URL; 4 5export async function fetchArticles() { 6 const response = await axios.get(`${strapiUrl}/api/articles?populate=*`); 7 return response.data.data; 8} 9 10export async function fetchArticle(slug) { 11 const response = await axios.get(`${strapiUrl}/api/articles?filters[slug][$eq]=${slug}&populate=*`); 12 return response.data.data; 13}
Create your Astro pages and components. Here's a simple example for the homepage (
src/pages/index.astro
):1--- 2import { fetchArticles } from '../lib/strapi'; 3const articles = await fetchArticles(); 4--- 5 6<html lang="en"> 7<head> 8 <meta charset="utf-8" /> 9 <title>My Blog</title> 10</head> 11<body> 12 <h1>Welcome to My Blog</h1> 13 <ul> 14 {articles.map((article) => ( 15 <li> 16 <a href={`/article/${article.attributes.slug}`}> 17 {article.attributes.title} 18 </a> 19 </li> 20 ))} 21 </ul> 22</body> 23</html>
Create a dynamic route for individual articles (
src/pages/article/[slug].astro
):1--- 2import { fetchArticle, fetchArticles } from '../../lib/strapi'; 3 4export async function getStaticPaths() { 5 const articles = await fetchArticles(); 6 return articles.map((article) => ({ 7 params: { slug: article.attributes.slug }, 8 })); 9} 10 11const { slug } = Astro.params; 12const article = await fetchArticle(slug); 13--- 14 15<html lang="en"> 16<head> 17 <meta charset="utf-8" /> 18 <title>{article.attributes.title}</title> 19</head> 20<body> 21 <h1>{article.attributes.title}</h1> 22 <div set:html={article.attributes.content}></div> 23</body> 24</html>
Key Integration Points
- Environment Variables: Use
.env
files to store the Strapi URL, making it easy to switch between development and production environments. - Data Fetching: The
strapi.js
utility file centralizes API calls, making it easier to manage and update data fetching logic. - Dynamic Routes: Astro's
getStaticPaths
function generates static pages for each article based on Strapi data. - Rich Text Rendering: Use the
set:html
directive to safely render rich text content from Strapi.
For more information on deployment strategies, explore various Strapi deployment options to find the best fit for your application.
Common Challenges and Solutions
Authentication and Permissions:
- Challenge: Ensuring the Strapi API is accessible to Astro during builds.
- Solution: Configure Strapi's roles and permissions to allow public access to necessary endpoints, or use API tokens for more secure access.
Handling Media and Assets:
- Challenge: Displaying images and other media stored in Strapi.
Solution: Use Astro's built-in Image component and pass the full URL of Strapi-hosted images:
1--- 2import { Image } from 'astro:assets'; 3--- 4 5<Image src={`${import.meta.env.STRAPI_URL}${article.attributes.featuredImage.data.attributes.url}`} alt="Featured Image" />
Optimizing Build Times:
- Challenge: Large content sets can slow down builds.
- Solution: Implement pagination in your Strapi queries and Astro's
getStaticPaths
to build pages in batches.
Content Updates:
- Challenge: Reflecting Strapi content changes on the Astro site.
- Solution: Set up a webhook in Strapi to trigger a new Astro build when content is published or updated.
For more advanced applications, such as building multi-tenant apps with Strapi, you can adapt these techniques to suit your project's needs.
By following this example and addressing common challenges, developers can create a powerful, content-driven website that uses the strengths of both Astro and Strapi. The static generation capabilities of Astro combined with Strapi's flexible content management provide an excellent foundation for building fast, scalable, and easily maintained web projects.
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 at 12:30 pm – 1:30 pm CST.
For more details, visit the Strapi documentation and Astro documentation.