The Problem
I needed 108 unique pages for my AI fortune telling website - one for every combination of 12 zodiac signs, 22 tarot cards, and 9 life path numbers. Writing them by hand? No chance.
The Solution: Dynamic Routes + getStaticPaths
Next.js makes this trivially easy with dynamic routes and static generation.
Step 1: Create the route file
pages/zodiac/[sign].js -> /zodiac/aries, /zodiac/taurus, etc.
pages/tarot/[card].js -> /tarot/the-fool, /tarot/the-magician, etc.
pages/numerology/[number].js -> /numerology/1, /numerology/2, etc.
Step 2: Define your data
// lib/zodiac-data.js
const SIGNS = ['aries','taurus','gemini','cancer','leo','virgo',
'libra','scorpio','sagittarius','capricorn','aquarius','pisces'];
const SIGN_DATA = {
aries: { element: 'Fire', ruling: 'Mars', dates: 'Mar 21 - Apr 19' },
taurus: { element: 'Earth', ruling: 'Venus', dates: 'Apr 20 - May 20' },
// ... etc
};
export { SIGNS, SIGN_DATA };
Step 3: Use getStaticPaths + getStaticProps
// pages/zodiac/[sign].js
import { SIGNS, SIGN_DATA } from '../../lib/zodiac-data';
export async function getStaticPaths() {
return {
paths: SIGNS.map(sign => ({ params: { sign } })),
fallback: false,
};
}
export async function getStaticProps({ params }) {
const sign = params.sign;
const data = SIGN_DATA[sign];
return {
props: { sign, data },
};
}
export default function ZodiacPage({ sign, data }) {
return (
<div>
<h1>{sign.charAt(0).toUpperCase() + sign.slice(1)}</h1>
<p>Element: {data.element}</p>
<p>Ruling Planet: {data.ruling}</p>
<p>Dates: {data.dates}</p>
{/* Add your content, SEO meta, structured data here */}
</div>
);
}
Step 4: Add structured data (JSON-LD)
// In your page component
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'Article',
headline: `${sign} Horoscope - Free AI Reading`,
description: `Discover your ${sign} personality traits with AI-powered cross-system analysis.`,
url: `https://your-site.com/zodiac/${sign}`,
};
// In your <Head>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
Step 5: Generate the sitemap automatically
// pages/sitemap.xml.js
import { SIGNS } from '../lib/zodiac-data';
export async function getServerSideProps({ res }) {
const baseUrl = 'https://your-site.com';
const urls = SIGNS.map(s => `${baseUrl}/zodiac/${s}`);
// Add tarot cards, numerology pages, etc.
const xml = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${urls.map(url => ` <url><loc>${url}</loc></url>`).join('\n')}
</urlset>`;
res.setHeader('Content-Type', 'text/xml');
res.write(xml);
res.end();
return { props: {} };
}
export default function Sitemap() { return null; }
The Result
- 108 unique pages generated at build time
- Each page has unique content, meta tags, and structured data
- Google indexed 80+ pages within 48 hours of submission
- Total build time: under 2 minutes
What About SEO Impact?
Here is what happened after I submitted the sitemap to Google Search Console:
- Day 1: Google discovered 108 pages
- Day 3: 42 pages indexed
- Day 7: 89 pages indexed
- Day 14: First organic traffic from long-tail queries
The key insight: long-tail pages compound. Each page targets a specific query like "aries tarot reading" or "life path number 8 meaning". Individually they get 10-50 searches/month, but across 108 pages that adds up.
Full Project
This is part of CyberOmen - my AI fortune telling website built as a one-person company. The whole thing runs on Next.js + Vercel for $0/month.
Want me to share the full code? Let me know in the comments!
Have you used dynamic routes for SEO? What was your experience?
Top comments (0)