Hey there!
So… this is my first blog on DEV.to 😅
I’ve been working with Next.js and Strapi for a while, and honestly, the combo is chef’s kiss, but most tutorials only teach the basics:
- Fetch API ✅
- Render data ✅
- Deploy ✅
Cool. But…
When you start working on real projects, you quickly realize there’s a big difference between “it works” and “it’s built like a pro”.
Today, I’m sharing two game-changing tips I wish someone told me earlier.
They’re not complicated — but they’ll make your Next.js + Strapi projects faster, safer, and production-ready.
Tip #1 — Mixing Static + Live Data (Hybrid Rendering)
Here’s the thing:
If you render everything live from Strapi → your site is slower.
If you make everything static → your content might get outdated.
The sweet spot? Hybrid Rendering:
Important stuff = Static + Incremental Static Regeneration (ISR)
Frequently changing stuff = Live fetch (SSR)
Example:
Imagine a blog post where the article is static (good for SEO), but comments are live (good for users).
// app/blog/[slug]/page.tsx
export const revalidate = 60; // Refresh static parts every 60s
async function getArticle(slug: string) {
const res = await fetch(`${process.env.NEXT_PUBLIC_STRAPI_URL}/articles?filters[slug][$eq]=${slug}&populate=*`, {
next: { revalidate: 60 }
});
return res.json();
}
async function getComments(articleId: number) {
const res = await fetch(`${process.env.NEXT_PUBLIC_STRAPI_URL}/comments?filters[article][id][$eq]=${articleId}`, {
cache: 'no-store' // Always fresh
});
return res.json();
}
export default async function BlogPost({ params }) {
const { data: articleData } = await getArticle(params.slug);
const article = articleData[0];
const { data: comments } = await getComments(article.id);
return (
<main>
<h1>{article.attributes.title}</h1>
<div dangerouslySetInnerHTML={{ __html: article.attributes.content }} />
<section>
<h2>Live Comments</h2>
{comments.map(c => (
<p key={c.id}>{c.attributes.text}</p>
))}
</section>
</main>
);
}
Why this is awesome:
✅ Pages load fast for SEO
✅ Users get the latest comments without a page rebuild
✅ Works perfectly for blogs, news, and product pages
Tip #2 — Don’t Trust Your API (Validate Everything)
Here’s a hard truth:
If your Strapi content changes shape, your frontend can break.
To prevent that → I use Zod for validation. It checks the API response before rendering. If something’s wrong, you’ll catch it early.
npm install zod
// lib/strapi.ts
import { z } from "zod";
const ArticleSchema = z.object({
id: z.number(),
attributes: z.object({
title: z.string(),
content: z.string(),
publishedAt: z.string(),
}),
});
export async function fetchArticles() {
const res = await fetch(`${process.env.NEXT_PUBLIC_STRAPI_URL}/articles`, {
cache: "no-store"
});
const json = await res.json();
return z.array(ArticleSchema).parse(json.data); // Validation here
}
Then in your page:
// app/page.tsx
import { fetchArticles } from "@/lib/strapi";
export default async function HomePage() {
const articles = await fetchArticles();
return (
<main>
{articles.map(a => (
<article key={a.id}>
<h2>{a.attributes.title}</h2>
<p>{a.attributes.content}</p>
</article>
))}
</main>
);
}
Why this is awesome:
✅ No random runtime errors
✅ Auto-documents your data structure
✅ Saves you from late-night debugging
Final Thoughts
Next.js + Strapi is already a great stack, but when you start mixing static + live data and validating API responses, your projects go from “works fine” → rock solid.
These two tips are small changes, but in real-world projects, they make a massive difference.
And since this is my first blog, if you try these out, I’d love to hear how it went! 🚀
Top comments (0)