vercel/platforms

repository·main·Indexed 27 days ago

https://github.com/vercel/platforms

A production-ready Next.js 16 example for building multi-tenant applications. It features a proxy-based routing system for custom subdomains, Redis for tenant data storage via Upstash, and a dedicated admin panel. The project includes utilities for subdomain data management, such as getSubdomainData and getAllSubdomains, and is optimized for deployment on Vercel with wildcard DNS support.

Tokens
1K
Snippets
2
Records
10
Agent score
92%

What's inside vercel-platforms

  1. Understand the Multi-Tenant Architecture

    main

    This project implements a subdomain-based multi-tenant architecture with the following characteristics:

    • Routing: A proxy (proxy.ts, which replaces middleware.ts in Next.js 16) detects subdomains and routes requests to the correct tenant.
    • Tenant Identification: Each tenant is identified by its subdomain (e.g., tenant.yourdomain.com).
    • Data Storage: Tenant data is stored in Redis using the subdomain:{name} key pattern.
    • Domain Structure: The main domain hosts the landing page and admin interface, while subdomains are dynamically mapped to tenant-specific content.
    • Environment Support: The proxy is designed to work across local development, production, and Vercel preview deployments.
  2. Configure environment variables for Upstash Redis

    main

    The application requires Upstash Redis for tenant data storage. Create a .env.local file in the root directory and provide your Redis credentials using the following keys:

    KV_REST_API_URL=your_redis_url
    KV_REST_API_TOKEN=your_redis_token
  3. Install and run the Next.js Multi-Tenant Example

    main

    To set up the multi-tenant application locally, follow these steps:

    1. Clone the repository:
      git clone https://github.com/vercel/platforms.git
      cd platforms
    2. Install dependencies using pnpm (recommended):
      pnpm install
    3. Configure environment variables in a .env.local file.
    4. Start the development server:
      pnpm dev

    Once running, you can access:

    • Main site: http://localhost:3000
    • Admin panel: http://localhost:3000/admin
    • Tenants: http://[tenant-name].localhost:3000
    git clone https://github.com/vercel/platforms.git
    cd platforms
    pnpm install
    pnpm dev
  4. Deploy the Multi-Tenant application to Vercel

    main

    The application is optimized for Vercel. To deploy:

    1. Push your repository to GitHub.
    2. Connect your repository to Vercel.
    3. Configure the required environment variables in the Vercel dashboard.
    4. Deploy the project.

    Important for Custom Domains: To support tenant subdomains, you must:

    1. Add your root domain to Vercel.
    2. Set up a wildcard DNS record (*.yourdomain.com) on Vercel.
  5. Configure Redis client via environment variables

    main

    The application uses an @upstash/redis client instance initialized with the following environment variables. Ensure these are set in your deployment environment to enable tenant data storage:

    • KV_REST_API_URL: The URL for the Upstash Redis REST API.
    • KV_REST_API_TOKEN: The authentication token for the Upstash Redis REST API.
  6. Configure root domain and protocol via environment variables

    main

    The application uses the following environment variables to determine the base URL and protocol:

    • NEXT_PUBLIC_ROOT_DOMAIN: Sets the root domain for the application. Defaults to localhost:3000 if not provided.
    • NODE_ENV: Determines the protocol. If set to production, the protocol constant is https; otherwise, it is http.
  7. Validate icon strings with isValidIcon()

    main
    Use isValidIcon(str) to validate if a string is suitable for use as an icon. The function checks if the string is 10 characters or fewer and attempts to verify if it contains at least one emoji character using Unicode property escapes. If the environment does not support Unicode property escapes, it falls back to checking if the string length is between 1 and 10 characters.
  8. List all subdomains with getAllSubdomains()

    main

    Use getAllSubdomains() to retrieve a list of all registered subdomains and their associated metadata. It scans Redis for keys matching the subdomain:* pattern.

    Returns an array of objects with the following structure:

    • subdomain: string
    • emoji: string (defaults to '❓' if not found)
    • createdAt: number (defaults to current timestamp if not found)
  9. Use the cn utility for class merging

    main
    The cn function is a utility used to merge Tailwind CSS classes safely. It combines clsx for conditional class logic and tailwind-merge to resolve Tailwind class conflicts (ensuring the last class provided wins).
  10. Retrieve data for a specific subdomain with getSubdomainData()

    main

    Use getSubdomainData(subdomain) to fetch metadata associated with a specific subdomain from Redis. The function automatically sanitizes the input by converting it to lowercase and removing all characters except lowercase letters, numbers, and hyphens.

    Returns a SubdomainData object containing:

    • emoji: string
    • createdAt: number