Skip to content

datoga/miniapps

Repository files navigation

Mini Apps Monorepo

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.

Features

  • 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-intl and 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

Requirements

  • 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.

Getting Started

Installation

npm install

Development

Run all apps in development mode:

npm run dev

Run a specific app:

npm run dev --workspace=whitelabel-demo
npm run dev --workspace=day1-mentoring

Build

Build all apps:

npm run build

Build a specific app:

npm run build --workspace=whitelabel-demo

Type Checking

npm run typecheck

Linting

npm run lint

Project Structure

├── 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

Internationalization (i18n)

This template uses next-intl for internationalization with localized routing.

Supported Locales

  • Spanish (es) - Default
  • English (en)

URL Structure

All apps use locale-prefixed URLs:

  • /es/ - Spanish version
  • /en/ - English version

Message Files

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.

Adding Translations

  1. Add the key to both locale files (en.json and es.json)
  2. Use useTranslations() hook to access the messages:
import { useTranslations } from "next-intl";

function MyComponent() {
  const t = useTranslations("namespace");
  return <h1>{t("key")}</h1>;
}

Theming

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 Configuration

Tailwind is configured with darkMode: "class" to support theme switching.

Google Analytics (GA4)

To enable Google Analytics:

  1. Copy .env.example to .env.local in your app directory
  2. Set your GA4 Measurement ID:
NEXT_PUBLIC_GA_ID=G-XXXXXXXXXX

Tracking Events

Use the trackEvent function from @miniapps/analytics:

import { trackEvent } from "@miniapps/analytics";

// Track an event
trackEvent("button_click", { button_name: "signup" });

PWA (Progressive Web App)

Every mini app is installable as a PWA with a Web App Manifest and dynamically generated icons.

How It Works

  • Each app exposes a manifest at /manifest.webmanifest (generated from app/manifest.ts)
  • Icons are dynamically generated using next/og ImageResponse (no binary PNG files in the repo)
  • Apple touch icons are provided for iOS home screen installation

Files Per App

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)

Testing PWA Installability

  1. Run the app in development mode:
npm run dev --workspace=whitelabel-demo
  1. Open Chrome DevTools > Application > Manifest
  2. Verify:
    • Manifest is detected
    • Icons (192x192 and 512x512) load successfully
    • "Install" button appears in the browser address bar

Notes

  • Service Worker: Optional - some apps (e.g., day7-replacedbyai) include Service Workers for offline caching
  • start_url: Set to /?utm_source=pwa&utm_medium=installed for PWA install tracking in Analytics
  • Icons: Generated on-the-fly with app initials and unique theme colors per app

Browser Storage

The @miniapps/storage package provides browser persistence helpers.

IndexedDB (Recommended)

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");

localStorage (Fallback)

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");

Creating a New Mini App

  1. Copy an existing app:
cp -r apps/whitelabel-demo apps/my-new-app
  1. Update package.json:

    • Change the name field
    • Update the dev port if needed
  2. Update messages:

    • Edit messages/en.json and messages/es.json
    • Update app-specific translations
  3. Update metadata:

    • Edit app/[locale]/layout.tsx to update title and description
  4. Update PWA files:

    • Edit app/manifest.ts to update app name, description, and theme_color
    • Edit app/icon.tsx to update APP_INITIALS and BG_COLOR
    • Edit app/apple-icon.tsx to match icon.tsx colors
  5. Install dependencies:

npm install
  1. Run the app:
npm run dev --workspace=my-new-app

Vercel Deployment

Each app can be deployed as a separate Vercel project.

Setup

  1. Create a new Vercel project
  2. Connect your GitHub repository
  3. Set the Root Directory to apps/<app-name> (e.g., apps/whitelabel-demo)
  4. Set environment variables if needed:
    • NEXT_PUBLIC_GA_ID - Google Analytics ID (optional)

Build Settings

Vercel will automatically detect the Next.js app. The recommended settings are:

  • Build Command: npm run build
  • Output Directory: .next
  • Install Command: npm install

Deploy Multiple Apps

To deploy multiple apps from the same repository:

  1. Create a separate Vercel project for each app
  2. Set the Root Directory for each project to the specific app folder
  3. Optionally configure different environment variables per project

Shared Packages

@miniapps/ui

Shared UI components:

  • ThemeProvider - Theme context provider
  • ThemeToggle - Theme switching component
  • LocaleSwitcher - Language switching component
  • AppShell - App layout with header and footer
  • Header - App header component
  • Footer - App footer with contact link and copyright
  • Button - Reusable button component
  • Modal - Accessible modal dialog with i18n support
  • ConfirmDialog - Confirmation dialog with variants (default, warning, danger)
  • ModalLabelsProvider / ModalLabelsWrapper - Context for translated modal labels
  • useShare / buildShareText - Web Share API utilities
  • cn - Utility for merging Tailwind classes

@miniapps/i18n

Internationalization utilities:

  • locales - Array of supported locales
  • defaultLocale - Default locale
  • mergeMessages - Merge common and app messages
  • getLocalizedPathname - Get pathname for a locale

@miniapps/analytics

Analytics utilities:

  • trackEvent - Track GA4 events
  • GoogleAnalyticsScript - GA4 script component

@miniapps/storage

Browser storage utilities:

  • getJSON, setJSON, remove - IndexedDB operations
  • local.getJSON, local.setJSON, local.remove - localStorage operations

@miniapps/seo

SEO utilities:

  • generateSEOMetadata - Generate comprehensive Next.js metadata
  • generateJsonLd - Generate JSON-LD structured data for WebApplication
  • generateSitemap - Generate sitemap with locale support
  • generateOgImage - Generate dynamic OpenGraph images
  • generateViewport - Generate viewport config with theme colors

@miniapps/drive

Google Drive sync integration:

  • DriveProvider - Context provider for Drive sync state
  • useDrive - Hook for Drive operations
  • DrivePickerScript - Google Picker integration

License

MIT

About

No description, website, or topics provided.

Resources

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •