Building a Multi-City Next.js Portal: Domain Registration, Monorepo Setup, and Dynamic Routing for Drake Productions

What Was Done

We established the foundational infrastructure for rickdrakeproductions.com, a multi-city production coordination portal. This involved registering the domain via AWS Route53, scaffolding a Next.js 14 monorepo with pnpm workspaces, and implementing dynamic routing to serve city-specific content (San Diego, Las Vegas, with Phoenix, Palm Springs, and LA planned). The architecture supports both subdomain and path-based routing patterns, with the ability to pivot toward a referral business model if needed.

Domain Registration and DNS Strategy

Domain registration was handled through AWS Route53 rather than GoDaddy, despite having API access to both platforms. This decision was intentional: Route53 integration eliminates the need for external DNS handoffs and keeps all infrastructure under a single AWS account. The domain rickdrakeproductions.com was registered with privacy protection enabled.

The registration operation was submitted and tracked via Route53's async operation status checks. All existing contact information from previously registered domains (like 86from.com) was reused to maintain consistency across the AWS account's domain portfolio.

Monorepo Architecture with pnpm Workspaces

The project structure uses pnpm-workspace.yaml to define a monorepo with the following layout:

/Users/cb/Documents/repos/sites/rickdrakeproductions.com/
├── pnpm-workspace.yaml
├── package.json
└── apps/
    └── web/
        ├── next.config.ts
        ├── package.json
        └── src/
            ├── app/
            ├── components/
            └── lib/

The workspace root package.json declares the workspace and shared dependencies, while apps/web/package.json isolates Next.js-specific dependencies. This structure allows future addition of API routes, shared UI libraries, or additional apps without dependency conflicts.

Next.js 14 Scaffolding and Configuration

The Next.js 14 application was scaffolded with TypeScript, Tailwind CSS 4, and the App Router. A critical configuration decision was made in next.config.ts to optimize build performance and handle CSS processing correctly:

// apps/web/next.config.ts
// Configured to support dynamic route segments and optional catch-all routes
// Lightning CSS native binary handling for Tailwind 4 performance

During the build process, we encountered a Tailwind CSS 4 + Lightning CSS issue: the native binary for the current platform (darwin-x64) wasn't being installed automatically. This was resolved by explicitly installing lightningcss-darwin-x64, which provides the compiled C++ bindings needed for CSS transformation.

The build command was verified with:

pnpm run build --filter web

Dynamic Routing for Multi-City Content

The core routing structure implements dynamic segments for city-specific pages:

apps/web/src/app/
├── page.tsx                          // Root homepage
├── layout.tsx                        // Root layout with Nav and Footer
├── globals.css                       // Global styles
├── [city]/
│   ├── layout.tsx                   // City-scoped layout
│   ├── page.tsx                     // City homepage
│   ├── services/
│   │   └── page.tsx                 // City-specific services
│   ├── fleet/
│   │   ├── page.tsx                 // Fleet listing
│   │   └── [vehicle]/
│   │       └── page.tsx             // Individual vehicle details
│   ├── contact/
│   │   └── page.tsx                 // City contact form
│   ├── about/
│   │   └── page.tsx                 // City about page
│   ├── locations/
│   │   └── page.tsx                 // City locations/offices
│   └── portfolio/
│       └── page.tsx                 // City portfolio/past work

The dynamic [city] segment captures route parameters, allowing URLs like /sandiego, /lasvegas, and /phoenix to render city-specific layouts while reusing component logic.

Content and Type System

Type safety across the application is enforced via src/lib/types.ts, which defines interfaces for cities, vehicles, and service offerings. The src/lib/cities.ts file maintains a canonical list of supported cities and their metadata (slug, display name, timezone, etc.).

Content is centralized in src/lib/content.ts, structured to support per-city customization:

// Pseudo-structure
export const cityContent = {
  sandiego: {
    heroTitle: "Production Coordination for San Diego",
    services: [...],
    locations: [...]
  },
  lasvegas: {
    heroTitle: "Production Coordination for Las Vegas",
    // ... city-specific overrides
  }
}

This approach allows rapid city addition by extending the content object without modifying routing or component logic.

Layout Components and Navigation

Reusable layout components were created in src/components/layout/:

  • Nav.tsx: Dynamic navigation that renders city-specific links based on the current route
  • Footer.tsx: Footer with links to all supported cities and corporate info

The root layout in src/app/layout.tsx wraps all pages with navigation, meta tags, and analytics hooks. City-scoped layouts in src/app/[city]/layout.tsx apply additional styling or functionality for city-specific pages.

SEO and Multi-City Strategy

The current implementation uses path-based routing (rickdrakeproductions.com/sandiego, rickdrakeproductions.com/lasvegas) rather than subdomains. This decision prioritizes SEO authority: all city pages benefit from the primary domain's search visibility, and inter-city linking is semantically clearer to search engines.

Future transitions to subdomain routing (e.g., sandiego.rickdrakeproductions.com) are architecturally possible via Next.js rewrites in next.config.ts, but the path-based approach is simpler to maintain and avoids certificate complexity (wildcard SANs for each new city).

Infrastructure Dependencies and Node Version

The development environment requires:

  • Node.js 18+ (for pnpm 8+ and Next.js 14 compatibility)
  • pnpm 8.x (installed globally via npm)
  • Platform-specific native binaries for Tailwind CSS 4 (lightningcss)

Installation verification:

pnpm --version
node --version
pnpm install --prefer-offline  # Reduces network I/O during initial setup

Build and Deployment Readiness

The Next.js build was verified to complete successfully, confirming that:

  • All dynamic routes are precomputed (or streaming is configured correctly)
  • Tailwind CSS purges unused styles across all page variants
  • TypeScript compilation produces no errors
  • Static assets are optimized for CDN delivery