DEV Community

Cover image for I Spent 50 Hours Building a Next.js Boilerplate So You Can Ship in 30 Minutes
Salman Shahriar
Salman Shahriar

Posted on • Edited on

I Spent 50 Hours Building a Next.js Boilerplate So You Can Ship in 30 Minutes

The Problem That Kept Me Up at Night

You know that feeling when you start a new Next.js project and spend the first week just setting things up? Authentication, internationalization, role management, SEO configuration... By the time you're done with the boilerplate, you've lost all that initial excitement.

What you get in one line: Type-safe i18n with RTL → NextAuth + Google OAuth → RBAC with parallel routes → SEO (sitemap, robots, manifest) → Dark mode → ESLint + Prettier → Vitest + Playwright → shadcn/ui → One config file. Production-ready.

I've been there. Too many times.

After launching my third SaaS project this year, I realized I was copy-pasting the same setup code over and over. So I decided to do something about it.

What I Built

Meet my production-ready Next.js boilerplate: not just another "hello world" starter template, but a fully-featured foundation that handles all the boring stuff so you can focus on building your actual product.

Important Links:

🔗 Live Demo | 📦 GitHub Repo | 🚀 Use this template | Deploy on Vercel

Boilerplate Screenshot

Why This Boilerplate is Different

🌍 Real Internationalization (Not Just a Dictionary)

I'm talking about type-safe translations that catch errors at compile time. No more broken translations in production because you typo'd a key.

Here's what makes it special:

  • Three languages out of the box: English, বাংলা (Bengali), and العربية (Arabic)
  • RTL support that actually works: Arabic layouts automatically flip to right-to-left
  • Dead-simple language switching: One click, zero page reload
  • Type-safe with TypeScript: Your IDE will tell you when a translation is missing
// TypeScript knows all your translation keys
t('navigation.home') // ✅ Works
t('navigation.homer') // ❌ Compile error - typo caught!
Enter fullscreen mode Exit fullscreen mode

🔐 Role-Based Access Control That Scales

Most tutorials show you basic auth and call it a day. But what about when you need different dashboards for users and admins? Or when you want to add a "Moderator" role later?

I used Next.js 15's parallel routes to make this painless:

app/
  (protected)/
    @admin/      # Admin-only views
      dashboard/
    @user/       # User views
      dashboard/
    layout.tsx   # Smart routing logic
Enter fullscreen mode Exit fullscreen mode

The layout automatically shows the right dashboard based on the user's role. No messy conditionals scattered everywhere. Want to add a new role? Just create a new parallel route folder. That's it.

🎨 A Design System That Doesn't Suck

I'm using shadcn/ui because:

  • Components are copy-paste ready (no bloated dependencies)
  • Full TypeScript support
  • Accessible by default (WCAG compliant)
  • Easy to customize without fighting CSS

Plus next-themes for light/dark mode with system preference detection and a manual toggle.

🔧 ESLint That Actually Helps (Not Annoys)

Let's be honest - most ESLint configs are either too strict or too loose. I spent time configuring rules that:

  • Catch real bugs (unused variables, missing dependencies, potential null references)
  • Enforce consistency (import order, naming conventions, formatting)
  • Don't get in your way (no annoying warnings for things that don't matter)
  • Work with Next.js 15 (proper App Router support, server component rules)

The config includes:

  • eslint-config-next - Official Next.js rules
  • TypeScript-specific linting
  • Import sorting and organization
  • Best practices for React hooks
  • Accessibility checks (a11y)

Prettier is wired up too (Tailwind plugin, format on save in .vscode/settings.json). Run npm run lint and npm run prettier:fix for consistent, clean code.

📊 SEO Configuration That's Actually Usable

Instead of hardcoding metadata everywhere, I created a single JSON configuration file that handles:

  • Open Graph tags
  • Twitter cards
  • Structured data (JSON-LD)
  • Multi-language meta tags
  • Canonical URLs
  • Dynamic sitemap generation

Just edit one file:

{
  "appName": "Your App",
  "title": "Your Title",
  "description": "Your Description",
  "domain": "https://yoursite.com",
  "keywords": ["your", "keywords"],
  "social": {
    "twitter": "@yourhandle"
  }
}
Enter fullscreen mode Exit fullscreen mode

Done. SEO handled. The same config drives sitemap (sitemap.ts), robots.txt (robots.ts), and manifest (manifest.ts).

🧪 Testing & CI

  • Unit and component tests: Vitest + React Testing Library. Run npm run test or npm run test:watch; npm run test:coverage for coverage.
  • E2E: Playwright in e2e/. Run npm run e2e (dev server starts automatically); npm run e2e:ui for the UI. Use npm run e2e:webkit for WebKit-only (e.g. to save disk).
  • CI: GitHub Actions – .github/workflows/check.yml runs lint, Prettier, tests, and build on push/PR; .github/workflows/playwright.yml runs E2E.

🔑 Authentication (NextAuth.js + Google OAuth)

Auth is built in with NextAuth.js. You get:

  • Google OAuth – enable by setting GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, and NEXT_PUBLIC_GOOGLE_AUTH_ENABLED=true in .env
  • Custom login page at /auth/login with optional "Sign in with Google"
  • Admin role by email – set AUTH_ADMIN_EMAILS=admin@yourdomain.com (comma-separated); those Google accounts get the admin role automatically
  • JWT session with role and user id; redirect to /dashboard after sign-in

Copy .env.example to .env, add your secrets, and you're done.

🏥 Health Check

GET /api/health returns { status: "ok" } for load balancers and Kubernetes probes.

How to Get Started (The Real Way)

Step 1: Clone and Install

# Grab the code
git clone https://github.com/salmanshahriar/nextjs-boilerplate-production-ready.git
cd nextjs-boilerplate-production-ready

# Install dependencies (use whatever you prefer)
npm install
# or bun install / yarn install / pnpm install
Enter fullscreen mode Exit fullscreen mode

Step 2: Configure Your Project

This is where most boilerplates leave you hanging. Not this one.

Edit lib/config/app-main-meta-data.json:

{
  "appName": "My Awesome SaaS",
  "title": "Revolutionary Product That Does X",
  "description": "We help Y achieve Z",
  "domain": "https://myawesomesaas.com",

  "organization": {
    "name": "My Company",
    "email": "hello@mycompany.com"
  },

  "social": {
    "twitter": "@myhandle",
    "github": "https://github.com/myhandle"
  }
}
Enter fullscreen mode Exit fullscreen mode

That's your entire brand configuration. One file.

Step 3: Customize Your Languages (Optional)

Want to add Spanish? Here's how:

  1. Create locales/es.json with the same structure as locales/en.json:
{
  "common": { "appName": "Mi App", ... },
  "navigation": {
    "home": "Inicio",
    "about": "Acerca de"
  }
}
Enter fullscreen mode Exit fullscreen mode
  1. Update lib/config/app-main-meta-data.json:
{
  "languages": {
    "supported": ["en", "bn", "ar", "es"],
    "locales": {
      "es": {
        "code": "es",
        "name": "Spanish",
        "nativeName": "Español",
        "locale": "es_ES",
        "direction": "ltr"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode
  1. In lib/i18n/get-translations.ts, import es.json and add es to the translations object. If you use strict translation keys, add the new locale to the TranslationKeys union in lib/i18n/types.ts.

Done. Your app now speaks Spanish.

Step 4: Set Up Your Roles

The boilerplate comes with User and Admin roles. To add more:

  1. Create a new parallel route folder:
mkdir -p app/(protected)/@moderator/dashboard
Enter fullscreen mode Exit fullscreen mode
  1. Add your pages inside that folder

  2. Update app/(protected)/layout.tsx to handle the new role:

if (currentUser?.role === 'moderator') return moderator
Enter fullscreen mode Exit fullscreen mode

That's genuinely all you need to do.

Step 5: Run It

npm run dev
Enter fullscreen mode Exit fullscreen mode

Open http://localhost:3000 and see your fully-configured app running.

Available Scripts

Command Description
npm run dev Start development server
npm run build Production build
npm run start Start production server
npm run lint Run ESLint
npm run lint:fix Fix ESLint errors
npm run test Unit tests (Vitest)
npm run test:watch Unit tests in watch mode
npm run test:coverage Tests with coverage
npm run e2e Playwright E2E tests
npm run e2e:ui Playwright with UI
npm run e2e:webkit E2E in WebKit only
npm run prettier Check formatting
npm run prettier:fix Fix formatting

Step 6: Environment (First-Time Setup)

Copy .env.example to .env. Set NEXT_PUBLIC_APP_URL if you need to override the site URL (e.g. in production). For Google sign-in: set NEXTAUTH_URL, NEXTAUTH_SECRET, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, then NEXT_PUBLIC_GOOGLE_AUTH_ENABLED=true. Optionally set AUTH_ADMIN_EMAILS=admin@yourdomain.com so those emails get the admin role.

Prerequisites

  • Node.js 18.17 or later
  • npm, yarn, pnpm, or bun

The Project Structure (Explained for Humans)

app/
  (protected)/           # Routes behind auth
    @admin/             # Admin-only pages
    @user/              # User pages
    layout.tsx          # Role-based routing

  api/                  # API routes
    auth/[...nextauth]/ # NextAuth handler
    health/             # GET /api/health → { status: "ok" }
  auth/login/           # Login page
  unauthorized/         # 403-style page

  layout.tsx            # Root layout (theme, i18n)
  page.tsx              # Landing page
  not-found.tsx         # 404
  manifest.ts           # PWA manifest from config
  robots.ts             # Robots.txt from config
  sitemap.ts            # Dynamic sitemap from config

components/
  ui/                   # shadcn/ui
  layout/               # Header, sidebar, theme toggle
  language-switcher.tsx

locales/
  en.json, bn.json, ar.json

lib/
  auth/                 # NextAuth options, session, auth context
  config/
    app-main-meta-data.json
    site.ts             # baseUrl, supportedLocales
  i18n/
    get-translations.ts
    language-context.tsx
    use-translations.ts
    types.ts
  utils.ts

e2e/                    # Playwright E2E tests
.github/workflows/      # CI: check.yml, playwright.yml
Enter fullscreen mode Exit fullscreen mode

What You Get Out of the Box

Next.js 15 with App Router and Server Components

TypeScript (strict mode)

Tailwind CSS

ESLint and Prettier (Next.js, TypeScript, a11y, format on save in .vscode)

NextAuth.js with optional Google OAuth and admin-by-email

i18n with type safety and RTL (en, bn, ar)

RBAC with parallel routes (User / Admin)

SEO from one JSON config (metadata, sitemap, robots, manifest)

next-themes for dark mode (system + manual toggle)

shadcn/ui (accessible, customizable)

Vitest + React Testing Library for unit/component tests

Playwright for E2E in e2e/

GitHub Actions for lint, format, test, build and E2E

Health check at GET /api/health

Vercel-ready (one-click deploy from the repo)

Real Talk: When Should You Use This?

Perfect for:

  • SaaS products with multiple user types
  • International applications
  • MVPs that need to look professional
  • Projects where you want to ship fast

Maybe not ideal for:

  • Simple landing pages (too much infrastructure)
  • Projects with very specific auth requirements (you'll need to customize heavily)
  • Apps that don't need i18n or role management

What I Learned Building This

  1. Parallel routes are underrated: They make role-based routing so much cleaner than conditional rendering
  2. Type-safe i18n is worth the setup: Catching translation bugs at compile time saves hours of debugging
  3. JSON configuration > hardcoded values: When you can change your entire SEO strategy by editing one file, you move faster
  4. Boilerplates should be opinionated: Too many options = decision fatigue. I made the tough choices so you don't have to

Contributing & Support

Found a bug? Want to add a feature? The repo is fully open source:

🐛 Report issues

Star on GitHub

🤝 Submit a PR

Final Thoughts

I built this because I got tired of setting up the same infrastructure for every project. If you're launching a product and don't want to spend two weeks on boilerplate, give it a try.

It's saved me probably 30+ hours across my last three projects. Maybe it'll help you too.


What's your biggest pain point when starting a new Next.js project? Drop a comment below - I'm always looking to improve this.

Happy building! 🚀

Links:

🔗 Live Demo | 📦 GitHub Repo | 🚀 Use this template | Deploy on Vercel

Top comments (20)

Collapse
 
anni profile image
Anietie Brownson

This is awesome
Good work

Collapse
 
salmanshahriar profile image
Salman Shahriar

Thanks man ‼️

Collapse
 
samihamahin profile image
Samiha Muntaha Mahin

Thats amazingg

Collapse
 
salmanshahriar profile image
Salman Shahriar

Thanks ‼️

Collapse
 
fahad_alikhan_5ec98c68a2 profile image
Fahad Ali Khan

Nice simple design. I'll surely use it in the future.

Collapse
 
salmanshahriar profile image
Salman Shahriar

❤️❤️

Collapse
 
sadi_nahin_5b099dbb050907 profile image
Sadi Nahin

Coolest shit, needed this!

Collapse
 
salmanshahriar profile image
Salman Shahriar

Thanks, man! Feel free to share any suggestions anytime! ❤️

Collapse
 
popy_chan_7f62c449a0c66c2 profile image
popy chan

damn! Good Work brother.

Collapse
 
salmanshahriar profile image
Salman Shahriar

thanks!

Collapse
 
sharafat_hossain_3dcc1f75 profile image
Sharafat Hossain

Mad respect man

Collapse
 
salmanshahriar profile image
Salman Shahriar

Thanks‼️

Collapse
 
leob profile image
leob

Nice! Bookmarked, and kept for "whenever I need it"

Collapse
 
salmanshahriar profile image
Salman Shahriar

Thanks, man! Feel free to share any suggestions anytime! ❤️

Collapse
 
joey_tribbiani_4771602dc5 profile image
Joey Tribbiani

Thanks for this blog.

Collapse
 
salmanshahriar profile image
Salman Shahriar • Edited

How you DOINNNN xD

Some comments may only be visible to logged-in visitors. Sign in to view all comments.