feature/site-meta

通过环境命令设置站点名称、描述
This commit is contained in:
Troray
2026-01-02 07:57:25 +08:00
parent d8da86054c
commit 9adb951c66
5 changed files with 97 additions and 7 deletions
+49 -1
View File
@@ -117,7 +117,49 @@ docker run -d -p 3000:3000 -e ACCESS_PASSWORD=your_secret_password --name kvideo
- **无法在界面删除**:只能通过修改环境变量更改
- **与本地密码兼容**:两种密码都可以解锁应用
## 自动订阅源配置
## 🎨 站点名称自定义配置
通过环境变量可以自定义站点名称、标题和描述,无需修改源代码。
### 可用环境变量:
| 变量名 | 说明 | 默认值 |
|--------|------|--------|
| `NEXT_PUBLIC_SITE_TITLE` | 浏览器标签页标题 | `KVideo - 视频聚合平台` |
| `NEXT_PUBLIC_SITE_DESCRIPTION` | 站点描述 | `Multi-source video aggregation platform with beautiful Liquid Glass UI` |
| `NEXT_PUBLIC_SITE_NAME` | 站点头部名称 | `KVideo` |
### 配置示例:
**Vercel 部署:**
在 Vercel 项目设置中添加环境变量:
- 变量名:`NEXT_PUBLIC_SITE_NAME`
- 变量值:`我的视频平台`
**Cloudflare Pages 部署:**
在 Cloudflare Pages 项目设置中添加环境变量:
- 变量名:`NEXT_PUBLIC_SITE_NAME`
- 变量值:`我的视频平台`
**Docker 部署:**
```bash
docker run -d -p 3000:3000 \
-e NEXT_PUBLIC_SITE_NAME="我的视频平台" \
-e NEXT_PUBLIC_SITE_TITLE="我的视频 - 聚合播放平台" \
-e NEXT_PUBLIC_SITE_DESCRIPTION="专属视频聚合播放平台" \
--name kvideo kuekhaoyang/kvideo:latest
```
**本地开发:**
在项目根目录创建 `.env.local` 文件:
```bash
NEXT_PUBLIC_SITE_NAME=我的视频平台
NEXT_PUBLIC_SITE_TITLE=我的视频 - 聚合播放平台
NEXT_PUBLIC_SITE_DESCRIPTION=专属视频聚合播放平台
```
## 📦 自动订阅源配置
可以通过环境变量 `NEXT_PUBLIC_SUBSCRIPTION_SOURCES` 自动配置订阅源,应用启动时会自动加载并设置为自动更新。
@@ -141,6 +183,12 @@ docker run -d -p 3000:3000 -e NEXT_PUBLIC_SUBSCRIPTION_SOURCES='[{"name":"MySour
- 变量名:`NEXT_PUBLIC_SUBSCRIPTION_SOURCES`
- 变量值:`[{"name":"...","url":"..."}]`
**Cloudflare Pages 部署:**
在 Cloudflare Pages 项目设置中添加环境变量:
- 变量名:`NEXT_PUBLIC_SUBSCRIPTION_SOURCES`
- 变量值:`[{"name":"...","url":"..."}]`
## 📝 自定义源 JSON 格式
如果你想创建自己的订阅源或批量导入源,可以使用以下 JSON 格式。
+3 -2
View File
@@ -5,6 +5,7 @@ import { ThemeProvider } from "@/components/ThemeProvider";
import { Analytics } from "@vercel/analytics/react";
import { ServiceWorkerRegister } from "@/components/ServiceWorkerRegister";
import { PasswordGate } from "@/components/PasswordGate";
import { siteConfig } from "@/lib/config/site-config";
const geistSans = Geist({
@@ -18,8 +19,8 @@ const geistMono = Geist_Mono({
});
export const metadata: Metadata = {
title: "KVideo - 视频聚合平台",
description: "Multi-source video aggregation platform with beautiful Liquid Glass UI",
title: siteConfig.title,
description: siteConfig.description,
icons: {
icon: '/icon.png',
},
+4 -3
View File
@@ -2,6 +2,7 @@ import Link from 'next/link';
import Image from 'next/image';
import { ThemeSwitcher } from '@/components/ThemeSwitcher';
import { Icons } from '@/components/ui/Icon';
import { siteConfig } from '@/lib/config/site-config';
interface NavbarProps {
onReset: () => void;
@@ -29,15 +30,15 @@ export function Navbar({ onReset, isSecretMode = false }: NavbarProps) {
<div className="w-8 h-8 sm:w-10 sm:h-10 relative flex items-center justify-center flex-shrink-0">
<Image
src="/icon.png"
alt="KVideo"
alt={siteConfig.name}
width={40}
height={40}
className="object-contain"
/>
</div>
<div className="flex flex-col min-w-0">
<h1 className="text-lg sm:text-2xl font-bold text-[var(--text-color)] truncate">KVideo</h1>
<p className="text-xs text-[var(--text-color-secondary)] hidden sm:block truncate"></p>
<h1 className="text-lg sm:text-2xl font-bold text-[var(--text-color)] truncate">{siteConfig.name}</h1>
<p className="text-xs text-[var(--text-color-secondary)] hidden sm:block truncate">{siteConfig.description}</p>
</div>
</Link>
+2 -1
View File
@@ -4,6 +4,7 @@ import Image from 'next/image';
import { Button } from '@/components/ui/Button';
import { ThemeSwitcher } from '@/components/ThemeSwitcher';
import { Icons } from '@/components/ui/Icon';
import { siteConfig } from '@/lib/config/site-config';
export function PlayerNavbar() {
const router = useRouter();
@@ -20,7 +21,7 @@ export function PlayerNavbar() {
>
<Image
src="/icon.png"
alt="KVideo"
alt={siteConfig.name}
width={40}
height={40}
className="object-contain"
+39
View File
@@ -0,0 +1,39 @@
/**
* Site Configuration
* Handles environment variables for site branding and customization
*/
export interface SiteConfig {
title: string;
description: string;
name: string;
}
/**
* Get site configuration from environment variables
* Falls back to default values if not set
*/
export function getSiteConfig(): SiteConfig {
return {
title: process.env.NEXT_PUBLIC_SITE_TITLE || "KVideo - 视频聚合平台",
description: process.env.NEXT_PUBLIC_SITE_DESCRIPTION || "Multi-source video aggregation platform with beautiful Liquid Glass UI",
name: process.env.NEXT_PUBLIC_SITE_NAME || "KVideo",
};
}
/**
* Get individual configuration values
*/
export const siteConfig = {
get title() {
return process.env.NEXT_PUBLIC_SITE_TITLE || "KVideo - 视频聚合平台";
},
get description() {
return process.env.NEXT_PUBLIC_SITE_DESCRIPTION || "Multi-source video aggregation platform with beautiful Liquid Glass UI";
},
get name() {
return process.env.NEXT_PUBLIC_SITE_NAME || "KVideo";
},
};