Transitioning a mature Next.js codebase to Astro can feel daunting, but the performance gains are worth it. In this case study, I moved a 50‑page blog from Next.js to Astro and achieved:
Here’s exactly how I approached it.
Export Content
Copied all Markdown files from the Next.js /posts
directory into Astro’s /src/content/posts
.
Routing Conversion
pages/blog/[slug].js
src/pages/blog/[slug].astro
Component Adaptation
.astro
islands when possible.Layout & Globals
_app.js
into a single src/layouts/BaseLayout.astro
.// pages/blog/[slug].js
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import ReactMarkdown from 'react-markdown';
export default function Post({ frontmatter, content }) {
return (
<article>
<h1>{frontmatter.title}</h1>
<ReactMarkdown>{content}</ReactMarkdown>
</article>
);
}
export async function getStaticProps({ params }) {
const filePath = path.join(process.cwd(), 'posts', `${params.slug}.md`);
const file = fs.readFileSync(filePath, 'utf-8');
const { data, content } = matter(file);
return { props: { frontmatter: data, content } };
}
export async function getStaticPaths() {
const files = fs.readdirSync(path.join('posts'));
const paths = files.map(name => ({
params: { slug: name.replace('.md', '') }
}));
return { paths, fallback: false };
}
Astro Blog Page
---
// src/pages/blog/[slug].astro
import { getCollection } from 'astro:content';
import Markdown from '@astrojs/markdown-remark';
export async function getStaticPaths() {
const posts = await getCollection('blog');
return posts.map(p => ({ params: { slug: p.slug } }));
}
const { data, body } = await Astro.resolve(
await Astro.glob('../content/posts/*.md')
).find(p => p.slug === Astro.params.slug);
---
<article>
<h1>{data.title}</h1>
<Markdown>{body}</Markdown>
</article>
⸻
Performance Metrics
Metric Next.js Astro
JS Bundle Size (KB) 280 85
Lighthouse Performance 87 100
Time to Interactive (s) 1.8 0.9
⸻
Lessons Learned
• Selective Hydration: Astro’s “islands” pattern lets you keep the majority of the site static and hydrate only where necessary.
• Simplified Builds: Removing unused JS and converting global layouts to a single Astro layout simplified builds by 30%.
• Developer Experience: Astro’s dev server is noticeably faster on large projects—hot reloads take under 200 ms.
Key Takeaway: Migrating to Astro can dramatically shrink bundles and boost performance with minimal rewrite effort—especially for content‑heavy sites.
©Copyright 2020 by Avid Tech Usa. Built with ♥ by Omar Madjitov.