How Open-SEO Handles Next.js Routing Without a `pages` Directory

Open-SEO does not use Next.js routing at all—it is a Vite-powered React application that defines routes explicitly in web/src/routes rather than using a pages directory.

While you might expect a modern React SEO tool to rely on Next.js file-system routing, the every-app/open-seo repository takes a fundamentally different approach. Instead of leveraging the classic pages/ convention that maps files to URLs automatically, this project opts for explicit route configuration with React Router. Understanding this architectural choice clarifies how navigation, code splitting, and rendering work throughout the codebase.

Why There Is No pages Directory

The most important distinction: Open-SEO is not a Next.js application. A quick check of [package.json](https://github.com/every-app/open-seo/blob/main/package.json) confirms that next appears nowhere in the dependency list. Instead, you'll find Vite and React Router handling all build and navigation concerns.

This design decision trades automatic file-system routing for explicit control. Rather than inferring routes from folder structure, developers register each route manually by exporting components from the web/src/routes directory. The router then maps these components to specific URL paths at runtime.

Where Routing Actually Lives: web/src/routes

The routing logic centralizes in web/src/routes, where each route is implemented as a standalone component. Consider the pricing page:

The underscore prefix in _marketing indicates this route belongs to a logical group—likely sharing layouts, analytics, or meta tag configurations—without affecting the public URL structure. When the application initializes, the router imports these components and builds its internal route table.

This pattern differs sharply from Next.js, where placing pages/pricing.tsx would automatically create the same route. Open-SEO's approach requires explicit registration but eliminates surprises from nested folders or dynamic segment conventions.

Build and Runtime Architecture

Three key files define how this non-Next.js routing stack operates:

File Purpose
[web/vite.config.ts](https://github.com/every-app/open-seo/blob/main/web/vite.config.ts) Configures the Vite dev server and production build pipeline
[web/worker-configuration.d.ts](https://github.com/every-app/open-seo/blob/main/web/worker-configuration.d.ts) Types the Cloudflare Worker handling edge-side rendering
web/src/routes/* Contains all routable page components

Since Vite manages the build, there is no next dev or next build process. Hot module replacement, code splitting, and asset optimization all flow through Vite's plugin ecosystem. The resulting static files deploy to Cloudflare's edge network, with [worker-configuration.d.ts](https://github.com/every-app/open-seo/blob/main/web/worker-configuration.d.ts) ensuring type-safe environment bindings for any server-side logic.

Handling SEO Without getStaticProps or getServerSideProps

Next.js developers rely on data fetching methods tied to the pages directory. Open-SEO replaces these with client-side data fetching and Cloudflare Worker edge rendering where needed.

  • For static content, components fetch data directly in useEffect hooks or receive props from parent layout components
  • For SEO-critical metadata, the _marketing/ route group likely applies consistent Open Graph and meta tag patterns
  • For dynamic rendering at the edge, the configured Cloudflare Worker intercepts requests and can inject server-rendered HTML before the React hydration completes

This architecture achieves SEO parity with Next.js while maintaining full control over the caching and rendering strategy.

Comparing Next.js vs. Open-SEO Routing Approaches

Aspect Next.js pages Open-SEO web/src/routes
Route discovery Automatic file-system crawling Explicit component imports
Dynamic routes [id].tsx file naming Router configuration object
Data fetching getStaticProps, getServerSideProps Client-side or Worker-side
Build tool Next.js compiler Vite
Deployment target Vercel-optimized Cloudflare Workers edge

Summary

  • Open-SEO uses Vite + React Router, not Next.js, so there is no pages directory
  • Routes live in web/src/routes with explicit path-to-component mapping
  • The _marketing/ subgroup organizes related pages without URL prefix changes
  • SEO and rendering handle through client-side hydration and Cloudflare Worker edge logic
  • [package.json](https://github.com/every-app/open-seo/blob/main/package.json) confirms zero Next.js dependencies

Frequently Asked Questions

Can I migrate Open-SEO to use Next.js file-system routing?

Not without substantial restructuring. The project tightly couples to Vite's build pipeline and React Router's navigation model. Converting to Next.js would require replacing the custom routing layer, adapting data fetching patterns, and migrating the Cloudflare Worker deployment to Next.js's preferred hosting models.

Why choose explicit routing over automatic file-system routing?

Explicit routing prevents accidental URL exposure when reorganizing code and enables complex route guards, code splitting boundaries, and nested layouts that file-system conventions struggle to express. The tradeoff is slightly more boilerplate when adding new pages.

How does Open-SEO achieve fast page loads without Next.js optimization?

Vite's aggressive code splitting and pre-bundling, combined with Cloudflare's edge caching, deliver comparable performance. The React Router-based navigation also supports lazy route loading, ensuring browsers only download JavaScript for routes users actually visit.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →