How to Configure the Site Name and Announcement in LunaTV

LunaTV determines the visible site name and announcement through a dual-layer configuration system that combines environment variables for static settings with a dynamic admin API for runtime updates.

LunaTV (MoonTechLab/LunaTV) is an open-source streaming platform built on Next.js that exposes its branding and notification settings through both build-time environment configuration and a database-backed admin interface. Whether you are deploying a new instance or managing an existing one, understanding how NEXT_PUBLIC_SITE_NAME interacts with the SiteConfig database records is essential for customizing the user experience.

Understanding the Configuration Architecture

The application reads configuration values from two distinct sources and merges them in src/app/layout.tsx. During server-side rendering, the code first checks for the NEXT_PUBLIC_SITE_NAME environment variable, falling back to "MoonTV" if undefined, and retrieves the announcement from config.SiteConfig.Announcement.

// src/app/layout.tsx
let siteName = process.env.NEXT_PUBLIC_SITE_NAME || 'MoonTV';
let announcement = config.SiteConfig.Announcement;

<SiteProvider siteName={siteName} announcement={announcement}>
  {/* Application tree */}
</SiteProvider>

These values are injected into the SiteProvider React context defined in src/components/SiteProvider.tsx, making them available to any component via the useSite() hook. This architecture ensures that environment variables define the hard-coded defaults, while the admin configuration allows runtime customization stored persistently in the database.

Method 1: Configure via Environment Variable

For static deployments where the site name should remain constant across restarts, set the NEXT_PUBLIC_SITE_NAME variable in your .env file or deployment platform.


# .env

NEXT_PUBLIC_SITE_NAME="MyCustomTV"

This value propagates throughout the application in three ways:

// scripts/generate-manifest.js
const siteName = process.env.NEXT_PUBLIC_SITE_NAME || 'MoonTV';
const manifest = { 
  name: siteName, 
  short_name: siteName,
  // ... additional fields
};

After modifying the environment variable, restart the Next.js server or trigger a redeployment to regenerate the manifest and apply changes to the site header and metadata.

Method 2: Configure via Admin API and UI

For dynamic updates without rebuilding the application, administrators can modify the site name and announcement through the built-in admin interface or by calling the REST API directly.

The admin UI located at src/app/admin/page.tsx sends a POST request to src/app/api/admin/site/route.ts with a JSON payload containing the new values:

{
  "SiteName": "MyAwesomeTV",
  "Announcement": "Welcome to the new version!"
}

API Endpoint Details:

  • URL: POST /api/admin/site
  • Content-Type: application/json
  • Body Fields:
    • SiteName: String to update the platform title
    • Announcement: String for the banner message (omit to hide the announcement banner)

Example using cURL:

curl -X POST https://your-domain.com/api/admin/site \
  -H "Content-Type: application/json" \
  -d '{"SiteName":"LunaStream","Announcement":"🚀 Maintenance scheduled for tonight"}'

Changes persist to the database immediately and take effect on the next page load, as src/app/layout.tsx reads from config.SiteConfig on every request.

Accessing Configuration in React Components

Any component within the LunaTV application can access the current configuration using the useSite() hook provided by SiteProvider.

import { useSite } from '@/components/SiteProvider';

export default function Header() {
  const { siteName, announcement } = useSite();

  return (
    <header>
      <h1>{siteName}</h1>
      {announcement && (
        <div className="announcement-banner">
          {announcement}
        </div>
      )}
    </header>
  );
}

The hook returns an object containing both siteName and announcement values, reflecting whichever source (environment variable or admin config) was active when the page was rendered.

Summary

  • Environment variables control the default site name and PWA manifest at build time via NEXT_PUBLIC_SITE_NAME in src/app/layout.tsx and scripts/generate-manifest.js
  • Admin API enables runtime updates to both site name and announcement through POST /api/admin/site, persisting changes to the database via src/app/api/admin/site/route.ts
  • React context propagates these values throughout the component tree via SiteProvider in src/components/SiteProvider.tsx, accessible through the useSite() hook
  • Announcement banners are optional; omitting the Announcement field in the API call or database hides the notification element in the UI

Frequently Asked Questions

Can I change the site name without restarting the server?

Yes. While environment variable changes require a restart, you can update the site name dynamically using the admin API at POST /api/admin/site. These changes take effect immediately on the next page load because src/app/layout.tsx reads config.SiteConfig.SiteName from the database on every request.

Why does the PWA manifest still show "MoonTV" after I updated the admin configuration?

The PWA manifest is generated at build time by scripts/generate-manifest.js, which only reads NEXT_PUBLIC_SITE_NAME from the environment. To update the manifest, you must set the environment variable before building, or regenerate the manifest file separately after deployment.

How do I hide the announcement banner completely?

Set the Announcement value to null, an empty string, or omit the field entirely when calling the admin API. The React components check for truthy values before rendering the banner, so a falsy value prevents the announcement from displaying:

{announcement && <div className="announcement">{announcement}</div>}

What happens if both the environment variable and admin config define a site name?

In src/app/layout.tsx, the code checks process.env.NEXT_PUBLIC_SITE_NAME first and uses it as the default value passed to SiteProvider. However, if your SiteProvider implementation merges these values, the admin configuration typically takes precedence for UI display. Check your specific version of src/components/SiteProvider.tsx to confirm the merge logic, as the context may override the SSR props with client-side data fetching.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →