A Turborepo-based monorepo template for building and deploying "1 mini app per day" projects to Vercel. Each app is a standalone Next.js application with shared packages for UI components, internationalization, analytics, SEO, and browser storage.
- Turborepo + npm workspaces - Fast, efficient monorepo management
- Next.js 16 App Router - Modern React framework with TypeScript
- PWA Installable - Web App Manifest and dynamic icons for every miniapp
- Internationalization (ES/EN) - Full i18n support with
next-intland localized routing - Theme Support - Light, dark, and system themes with
next-themes - SEO Optimized - Metadata, JSON-LD, sitemaps, and OG images
- Google Analytics GA4 - Optional analytics integration
- Browser Persistence - IndexedDB and localStorage helpers
- Google Drive Sync - Optional cloud backup with
@miniapps/drive - Shared UI Components - Reusable components across all apps
- Static/Client-only - No API routes by default
- Node.js:
>=24.0.0(v24.12.0 LTS recommended)
ℹ️ Note: This template requires Node.js 24 or later. Install with
nvm install 24 && nvm use 24.
npm installRun all apps in development mode:
npm run devRun a specific app:
npm run dev --workspace=whitelabel-demo
npm run dev --workspace=day1-mentoringBuild all apps:
npm run buildBuild a specific app:
npm run build --workspace=whitelabel-demonpm run typechecknpm run lint├── apps/
│ ├── whitelabel-demo/ # Full example app with all features
│ ├── day1-mentoring/ # Mentoring Tracker - Manage mentees and sessions
│ ├── day2-verbs/ # VerbMaster - English irregular verbs learning
│ ├── day3-qr/ # QR Library - Save and manage QR codes
│ ├── day4-bilbo/ # BilboTracker - Strength training tracker with charts
│ ├── day5-gamemaster/ # GameMaster - Tournament management (brackets, ladders)
│ ├── day6-recordme/ # RecordMe - Browser-based video recorder
│ └── day7-replacedbyai/ # Will AI Replace? - AI job impact analysis
├── packages/
│ ├── ui/ # Shared UI components
│ ├── i18n/ # Internationalization utilities
│ ├── analytics/ # Google Analytics helpers
│ ├── storage/ # Browser persistence (IndexedDB/localStorage)
│ ├── seo/ # SEO utilities (metadata, JSON-LD, sitemaps, OG images)
│ ├── drive/ # Google Drive sync integration
│ ├── config/ # Shared Tailwind and PostCSS configs
│ ├── eslint-config/ # Shared ESLint configuration
│ └── typescript-config/ # Shared TypeScript configuration
├── turbo.json # Turborepo configuration
└── package.json # Root package.json with workspaces
This template uses next-intl for internationalization with localized routing.
- Spanish (
es) - Default - English (
en)
All apps use locale-prefixed URLs:
/es/- Spanish version/en/- English version
Messages are stored in JSON files:
- Common messages:
packages/i18n/messages/common/{locale}.json - App-specific messages:
apps/{app}/messages/{locale}.json
Common messages are automatically merged with app-specific messages.
- Add the key to both locale files (
en.jsonandes.json) - Use
useTranslations()hook to access the messages:
import { useTranslations } from "next-intl";
function MyComponent() {
const t = useTranslations("namespace");
return <h1>{t("key")}</h1>;
}Theme support is provided by next-themes with three options:
- System - Follows OS preference
- Light - Light theme
- Dark - Dark theme
The theme toggle is visible on every page in the header.
Tailwind is configured with darkMode: "class" to support theme switching.
To enable Google Analytics:
- Copy
.env.exampleto.env.localin your app directory - Set your GA4 Measurement ID:
NEXT_PUBLIC_GA_ID=G-XXXXXXXXXXUse the trackEvent function from @miniapps/analytics:
import { trackEvent } from "@miniapps/analytics";
// Track an event
trackEvent("button_click", { button_name: "signup" });Every mini app is installable as a PWA with a Web App Manifest and dynamically generated icons.
- Each app exposes a manifest at
/manifest.webmanifest(generated fromapp/manifest.ts) - Icons are dynamically generated using
next/ogImageResponse (no binary PNG files in the repo) - Apple touch icons are provided for iOS home screen installation
app/
├── manifest.ts # Web App Manifest (name, icons, theme_color, etc.)
├── icon.tsx # Dynamic icon generation (32x32, 192x192, 512x512)
└── apple-icon.tsx # Apple touch icon (180x180)
- Run the app in development mode:
npm run dev --workspace=whitelabel-demo- Open Chrome DevTools > Application > Manifest
- Verify:
- Manifest is detected
- Icons (192x192 and 512x512) load successfully
- "Install" button appears in the browser address bar
- Service Worker: Optional - some apps (e.g.,
day7-replacedbyai) include Service Workers for offline caching - start_url: Set to
/?utm_source=pwa&utm_medium=installedfor PWA install tracking in Analytics - Icons: Generated on-the-fly with app initials and unique theme colors per app
The @miniapps/storage package provides browser persistence helpers.
import { getJSON, setJSON, remove } from "@miniapps/storage";
// Save data
await setJSON("user-preferences", { theme: "dark" });
// Load data
const prefs = await getJSON("user-preferences");
// Remove data
await remove("user-preferences");import { local } from "@miniapps/storage";
// Save data
local.setJSON("user-preferences", { theme: "dark" });
// Load data
const prefs = local.getJSON("user-preferences");
// Remove data
local.remove("user-preferences");- Copy an existing app:
cp -r apps/whitelabel-demo apps/my-new-app-
Update
package.json:- Change the
namefield - Update the dev port if needed
- Change the
-
Update messages:
- Edit
messages/en.jsonandmessages/es.json - Update app-specific translations
- Edit
-
Update metadata:
- Edit
app/[locale]/layout.tsxto update title and description
- Edit
-
Update PWA files:
- Edit
app/manifest.tsto update app name, description, and theme_color - Edit
app/icon.tsxto update APP_INITIALS and BG_COLOR - Edit
app/apple-icon.tsxto match icon.tsx colors
- Edit
-
Install dependencies:
npm install- Run the app:
npm run dev --workspace=my-new-appEach app can be deployed as a separate Vercel project.
- Create a new Vercel project
- Connect your GitHub repository
- Set the Root Directory to
apps/<app-name>(e.g.,apps/whitelabel-demo) - Set environment variables if needed:
NEXT_PUBLIC_GA_ID- Google Analytics ID (optional)
Vercel will automatically detect the Next.js app. The recommended settings are:
- Build Command:
npm run build - Output Directory:
.next - Install Command:
npm install
To deploy multiple apps from the same repository:
- Create a separate Vercel project for each app
- Set the Root Directory for each project to the specific app folder
- Optionally configure different environment variables per project
Shared UI components:
ThemeProvider- Theme context providerThemeToggle- Theme switching componentLocaleSwitcher- Language switching componentAppShell- App layout with header and footerHeader- App header componentFooter- App footer with contact link and copyrightButton- Reusable button componentModal- Accessible modal dialog with i18n supportConfirmDialog- Confirmation dialog with variants (default, warning, danger)ModalLabelsProvider/ModalLabelsWrapper- Context for translated modal labelsuseShare/buildShareText- Web Share API utilitiescn- Utility for merging Tailwind classes
Internationalization utilities:
locales- Array of supported localesdefaultLocale- Default localemergeMessages- Merge common and app messagesgetLocalizedPathname- Get pathname for a locale
Analytics utilities:
trackEvent- Track GA4 eventsGoogleAnalyticsScript- GA4 script component
Browser storage utilities:
getJSON,setJSON,remove- IndexedDB operationslocal.getJSON,local.setJSON,local.remove- localStorage operations
SEO utilities:
generateSEOMetadata- Generate comprehensive Next.js metadatagenerateJsonLd- Generate JSON-LD structured data for WebApplicationgenerateSitemap- Generate sitemap with locale supportgenerateOgImage- Generate dynamic OpenGraph imagesgenerateViewport- Generate viewport config with theme colors
Google Drive sync integration:
DriveProvider- Context provider for Drive sync stateuseDrive- Hook for Drive operationsDrivePickerScript- Google Picker integration
MIT