Dev.to WebDev ๐Ÿ›  Dev ๐Ÿ‘ 0 ๐Ÿ“– 3 min read

Building a Roblox Game Guide with Next.js 16, Tailwind CSS v4, and a Single-Source-of-Truth Routing System

I recently built Catch a Brainrot Guide, a fan-made resource hub for a Roblox creature-collection RPG. Here's a walkthrough of the tech stack and some architectural decisions that made the project interesting.

I recently built Catch a Brainrot Guide, a fan-made resource hub for a Roblox creature-collection RPG. Here's a walkthrough of the tech stack and some architectural decisions that made the project interesting.

Stack

  • Next.js 16 (App Router, static export)
  • React 19
  • Tailwind CSS v4 โ€” the new @theme directive means no more tailwind.config.ts
  • TypeScript 5.7
  • Cloudflare Pages for deployment

Single Source of Truth for Routes

All 20+ page routes live in one file: src/lib/routes.ts. Every route is typed with its path, label, sitemap priority, changefreq, and nav/footer placement.

export const ROUTES: RouteDef[] = [
  { path: '/tier-list', label: 'Tier List', priority: 0.9, changefreq: 'daily', nav: 'brainrots', footer: 'quick' },
  { path: '/guide/how-to-play', label: 'How to Play', priority: 0.8, changefreq: 'weekly', nav: 'guides' },
  // ... 20+ pages
];

The Navbar, Footer, and sitemap.ts all import from this single array. Adding a new page means one entry in routes.ts โ€” everything else syncs automatically.

// sitemap.ts โ€” auto-syncs from ROUTES
export default function sitemap(): MetadataRoute.Sitemap {
  return ROUTES.map((route) => ({
    url: route.path === '/' ? GAME.domain : `${GAME.domain}${route.path}`,
    lastModified: new Date(),
    changeFrequency: route.changefreq,
    priority: route.priority,
  }));
}

Tailwind CSS v4: Bye-Bye tailwind.config.ts

Tailwind v4 moves configuration into native CSS via @theme:

@import "tailwindcss";

@theme {
  --color-background: #0a0a0f;
  --color-foreground: #f1f5f9;
  --color-primary: #8b5cf6;
  --color-card: #14141f;
  --color-glass-border: rgba(255, 255, 255, 0.08);
}

SEO Architecture (Three Layers)

1. Global Metadata (layout.tsx)

Title templates, Open Graph, Twitter cards, robots directives, and canonical URL are set once in the root layout.

export const metadata: Metadata = {
  title: { default: `${GAME.name} - Roblox Game Guide, Codes & Wiki`, template: `%s | ${GAME.name}` },
  robots: { index: true, follow: true },
  alternates: { canonical: GAME.domain },
};

2. Page-Level JSON-LD Schemas

Every page injects context-specific structured data โ€” BreadcrumbList, FAQPage, or Article schemas.

const breadcrumbSchema = generateBreadcrumbSchema([
  { name: 'Home', url: '/' },
  { name: 'Tier List', url: '/tier-list' },
]);

3. IndexNow Auto-Submission

After each build, a script parses sitemap.xml and pushes all URLs to the IndexNow API (accepted by Bing, Yandex, Naver). No registration required.

const payload = {
  host: 'catchabrainrot.site',
  key: 'your-key',
  urlList: allUrls,
};
await fetch('https://api.indexnow.org/indexnow', { method: 'POST', body: JSON.stringify(payload) });

YouTube Embed: Facade Pattern

Instead of loading a 1MB+ YouTube iframe on page load, I use a facade โ€” a static thumbnail with a play button that swaps to the real iframe only on click.

export default function YouTubeEmbed({ videoId, title }: Props) {
  const [loaded, setLoaded] = useState(false);
  const thumbnail = `https://img.youtube.com/vi/${videoId}/mqdefault.jpg`;
  return loaded ? (
    <iframe src={`https://www.youtube.com/embed/${videoId}?autoplay=1`} />
  ) : (
    <button onClick={() => setLoaded(true)}>
      <img src={thumbnail} loading="lazy" fetchPriority="low" />
      <PlayIcon />
    </button>
  );
}

The "Honest Codes" Pattern

A common SEO play in Roblox guide sites is to fabricate fake codes to trap search traffic. I went the opposite direction: the /codes page transparently states the game has no code redemption system yet, and redirects users toward the official Discord for updates. It ranks well and earns trust โ€” a better long-term play than fake codes.

AI-Assisted Development

The repo includes an AGENTS.md that defines an SEO workflow: when a keyword research report lands, the agent analyzes priorities, checks existing coverage, generates new pages, updates sitemap/nav, runs an SEO audit, builds, and logs results. This turns keyword research into a semi-automated pipeline from idea to deployment.

Deployment

Static export to Cloudflare Pages, with IndexNow submission running post-build.

Takeaways

  • Single source of truth for routes eliminates maintenance drift
  • Structured SEO from day one beats retrofitting later
  • Honesty as a content strategy builds trust and ranks better than fabricated content

The full site is live at catchabrainrot.site. Questions or thoughts? Drop a comment below.

๐Ÿ“ฐ Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes โ€” full credit and traffic to the original publisher.