feat: 全面优化 SEO 元数据、结构化数据和站点地图

为所有工具页面添加 canonical URL、keywords、SoftwareApplication 和
BreadcrumbList 结构化数据,优化标题和描述以包含搜索意图关键词,
更新站点地图日期和优先级,移除无效的 SearchAction,新增 PWA manifest。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-08 09:17:29 +08:00
parent b365bc1201
commit 03cc0fd283
8 changed files with 295 additions and 66 deletions

View File

@@ -1,5 +1,6 @@
import type { Metadata } from "next";
import { headers } from "next/headers";
import { SoftwareApplicationStructuredData, BreadcrumbStructuredData } from "@/components/seo/StructuredData";
export async function generateMetadata(): Promise<Metadata> {
const headersList = await headers();
@@ -7,25 +8,61 @@ export async function generateMetadata(): Promise<Metadata> {
const lang = acceptLanguage.includes("zh") ? "zh" : "en";
const titles = {
en: "Audio Compression - Compress & Convert Audio Files",
zh: "音频压缩 - 压缩并转换音频文件",
en: "Audio Compression - Compress & Convert Audio Files Online Free",
zh: "音频压缩 - 免费在线压缩并转换音频文件",
};
const descriptions = {
en: "Compress and convert audio files to various formats including MP3, AAC, OGG, FLAC. Adjust bitrate and sample rate for optimal quality.",
zh: "压缩转换音频文件为多种格式,包括 MP3、AAC、OGG、FLAC。调整比特率采样率以获得最佳质量。",
en: "Free online audio compressor and converter. Compress MP3, WAV, OGG, AAC, FLAC files. Adjust bitrate, sample rate, channels. Browser-based with no uploads required.",
zh: "免费在线音频压缩转换工具。压缩 MP3、WAV、OGG、AAC、FLAC 文件。调整比特率采样率、声道。浏览器本地处理无需上传。",
};
const keywords = {
en: [
"audio compression",
"audio compressor online",
"compress MP3",
"audio converter",
"WAV to MP3",
"reduce audio size",
"audio bitrate converter",
"OGG converter",
"FLAC converter",
"browser-based",
],
zh: [
"音频压缩",
"在线音频压缩",
"MP3压缩",
"音频转换",
"WAV转MP3",
"缩小音频",
"音频比特率转换",
"OGG转换",
"FLAC转换",
"浏览器端",
],
};
const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || "https://kymr.top";
return {
title: titles[lang],
description: descriptions[lang],
keywords: keywords[lang],
alternates: {
canonical: `${baseUrl}/tools/audio-compress`,
},
openGraph: {
title: titles[lang],
description: descriptions[lang],
url: `${baseUrl}/tools/audio-compress`,
type: "website",
},
twitter: {
title: titles[lang],
description: descriptions[lang],
card: "summary_large_image",
},
};
}
@@ -35,5 +72,23 @@ export default function AudioCompressLayout({
}: {
children: React.ReactNode;
}) {
return children;
return (
<>
<SoftwareApplicationStructuredData
name="Audio Compressor - KYMR.TOP"
description="Free online audio compression and conversion tool. Support MP3, WAV, OGG, AAC, FLAC formats. Browser-based processing with no uploads."
url="/tools/audio-compress"
category="MultimediaApplication"
operatingSystem="Any (Browser-based)"
/>
<BreadcrumbStructuredData
items={[
{ name: "Home", url: "/" },
{ name: "Tools", url: "/tools" },
{ name: "Audio Compression", url: "/tools/audio-compress" },
]}
/>
{children}
</>
);
}

View File

@@ -1,5 +1,6 @@
import type { Metadata } from "next";
import { headers } from "next/headers";
import { SoftwareApplicationStructuredData, BreadcrumbStructuredData } from "@/components/seo/StructuredData";
export async function generateMetadata(): Promise<Metadata> {
const headersList = await headers();
@@ -7,25 +8,61 @@ export async function generateMetadata(): Promise<Metadata> {
const lang = acceptLanguage.includes("zh") ? "zh" : "en";
const titles = {
en: "Image Compression - Optimize Images for Web & Mobile",
zh: "图片压缩 - 为网页和移动端优化图片",
en: "Image Compression - Optimize PNG, JPEG, WebP Online Free",
zh: "图片压缩 - 免费在线优化 PNG、JPEG、WebP 图片",
};
const descriptions = {
en: "Optimize images for web and mobile without quality loss. Support for batch processing and format conversion including PNG, JPEG, WebP.",
zh: "为网页和移动端优化图片,不影响质量。支持批量处理和格式转换,包括 PNG、JPEG、WebP。",
en: "Free online image compressor. Optimize PNG, JPEG, WebP, AVIF images without quality loss. Batch processing, format conversion, browser-based with no uploads required.",
zh: "免费在线图片压缩工具。无损优化 PNG、JPEG、WebP、AVIF 图片。支持批量处理、格式转换,浏览器本地处理无需上传。",
};
const keywords = {
en: [
"image compression",
"image compressor online",
"compress PNG",
"compress JPEG",
"WebP converter",
"image optimizer",
"batch image compression",
"reduce image size",
"AVIF converter",
"browser-based",
],
zh: [
"图片压缩",
"在线图片压缩",
"PNG压缩",
"JPEG压缩",
"WebP转换",
"图片优化",
"批量压缩",
"缩小图片",
"AVIF转换",
"浏览器端",
],
};
const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || "https://kymr.top";
return {
title: titles[lang],
description: descriptions[lang],
keywords: keywords[lang],
alternates: {
canonical: `${baseUrl}/tools/image-compress`,
},
openGraph: {
title: titles[lang],
description: descriptions[lang],
url: `${baseUrl}/tools/image-compress`,
type: "website",
},
twitter: {
title: titles[lang],
description: descriptions[lang],
card: "summary_large_image",
},
};
}
@@ -35,5 +72,23 @@ export default function ImageCompressLayout({
}: {
children: React.ReactNode;
}) {
return children;
return (
<>
<SoftwareApplicationStructuredData
name="Image Compressor - KYMR.TOP"
description="Free online image compression tool. Optimize PNG, JPEG, WebP, AVIF images without quality loss. Browser-based processing with no uploads."
url="/tools/image-compress"
category="MultimediaApplication"
operatingSystem="Any (Browser-based)"
/>
<BreadcrumbStructuredData
items={[
{ name: "Home", url: "/" },
{ name: "Tools", url: "/tools" },
{ name: "Image Compression", url: "/tools/image-compress" },
]}
/>
{children}
</>
);
}

View File

@@ -1,5 +1,6 @@
import type { Metadata } from "next";
import { headers } from "next/headers";
import { SoftwareApplicationStructuredData, BreadcrumbStructuredData } from "@/components/seo/StructuredData";
export async function generateMetadata(): Promise<Metadata> {
const headersList = await headers();
@@ -7,47 +8,55 @@ export async function generateMetadata(): Promise<Metadata> {
const lang = acceptLanguage.includes("zh") ? "zh" : "en";
const titles = {
en: "Texture Atlas Generator - Create Sprite Sheets Online",
zh: "纹理图集生成器 - 在线创建精灵图",
en: "Texture Atlas Generator - Create Sprite Sheets Online Free",
zh: "纹理图集生成器 - 免费在线创建精灵图",
};
const descriptions = {
en: "Generate texture atlases and sprite sheets for game development. Pack multiple sprites into a single texture atlas with JSON data export. All processing happens locally in your browser.",
zh: "为游戏开发生成纹理图集和精灵图。将多个精灵打包到单个纹理图集中,支持导出 JSON 数据。所有处理都在您的浏览器本地进行。",
en: "Free online texture atlas and sprite sheet generator for game development. Pack multiple sprites into optimized atlases with JSON data export. Browser-based, no uploads needed.",
zh: "免费在线纹理图集和精灵图生成器,专为游戏开发设计。将多个精灵打包到优化的图集中,支持导出 JSON 数据。浏览器本地处理,无需上传。",
};
const keywords = {
en: [
"texture atlas",
"sprite sheet",
"game development",
"sprite sheet generator",
"texture packer online",
"sprite sheet creator",
"game development tools",
"sprite packer",
"texture packing",
"game assets",
"sprite generator",
"JSON export",
"game assets",
"texture atlas generator",
"browser-based",
],
zh: [
"纹理图集",
"精灵图",
"游戏开发",
"精灵图生成器",
"在线纹理打包",
"精灵图制作",
"游戏开发工具",
"精灵打包",
"纹理打包",
"游戏资产",
"精灵生成器",
"JSON导出",
"游戏资产",
"纹理图集生成器",
"浏览器端",
],
};
const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || "https://kymr.top";
return {
title: titles[lang],
description: descriptions[lang],
keywords: keywords[lang],
alternates: {
canonical: `${baseUrl}/tools/texture-atlas`,
},
openGraph: {
title: titles[lang],
description: descriptions[lang],
url: `${baseUrl}/tools/texture-atlas`,
type: "website",
},
twitter: {
@@ -63,5 +72,23 @@ export default function TextureAtlasLayout({
}: {
children: React.ReactNode;
}) {
return children;
return (
<>
<SoftwareApplicationStructuredData
name="Texture Atlas Generator - KYMR.TOP"
description="Free online texture atlas and sprite sheet generator. Pack multiple sprites into optimized atlases with JSON export. Browser-based processing."
url="/tools/texture-atlas"
category="DeveloperApplication"
operatingSystem="Any (Browser-based)"
/>
<BreadcrumbStructuredData
items={[
{ name: "Home", url: "/" },
{ name: "Tools", url: "/tools" },
{ name: "Texture Atlas", url: "/tools/texture-atlas" },
]}
/>
{children}
</>
);
}

View File

@@ -1,5 +1,6 @@
import type { Metadata } from "next";
import { headers } from "next/headers";
import { SoftwareApplicationStructuredData, BreadcrumbStructuredData } from "@/components/seo/StructuredData";
export async function generateMetadata(): Promise<Metadata> {
const headersList = await headers();
@@ -7,25 +8,59 @@ export async function generateMetadata(): Promise<Metadata> {
const lang = acceptLanguage.includes("zh") ? "zh" : "en";
const titles = {
en: "Video to Frame Sequence - Extract Frame Sequences from Videos",
zh: "视频转序列帧 - 从视频提取序列帧",
en: "Video to Frame Sequence - Extract Frames from Video Online Free",
zh: "视频转序列帧 - 免费在线从视频提取帧图片",
};
const descriptions = {
en: "Extract frame sequences from videos with customizable frame rates. Perfect for sprite animations and game asset preparation. Supports MP4, MOV, AVI, WebM.",
zh: "从视频中提取序列帧,可自定义帧率。非常适合精灵动画制作和游戏素材准备。支持 MP4、MOV、AVI、WebM。",
en: "Free online video to frame sequence extractor. Extract PNG, WebP, JPEG frames from MP4, WebM, MOV videos with custom frame rates. Perfect for sprite animations and game assets.",
zh: "免费在线视频转序列帧工具。从 MP4、WebM、MOV 视频中提取 PNG、WebP、JPEG 帧图片,可自定义帧率。非常适合精灵动画和游戏素材制作。",
};
const keywords = {
en: [
"video to frames",
"video frame extractor",
"extract frames from video",
"video to PNG sequence",
"video to sprite sheet",
"frame sequence generator",
"MP4 to frames",
"game animation frames",
"browser-based",
],
zh: [
"视频转序列帧",
"视频抽帧",
"视频帧提取",
"视频转PNG",
"视频转精灵图",
"序列帧生成",
"MP4转帧",
"游戏动画帧",
"浏览器端",
],
};
const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || "https://kymr.top";
return {
title: titles[lang],
description: descriptions[lang],
keywords: keywords[lang],
alternates: {
canonical: `${baseUrl}/tools/video-frames`,
},
openGraph: {
title: titles[lang],
description: descriptions[lang],
url: `${baseUrl}/tools/video-frames`,
type: "website",
},
twitter: {
title: titles[lang],
description: descriptions[lang],
card: "summary_large_image",
},
};
}
@@ -35,5 +70,23 @@ export default function VideoFramesLayout({
}: {
children: React.ReactNode;
}) {
return children;
return (
<>
<SoftwareApplicationStructuredData
name="Video Frame Extractor - KYMR.TOP"
description="Free online video to frame sequence tool. Extract PNG, WebP, JPEG frames from videos with custom frame rates. Browser-based processing."
url="/tools/video-frames"
category="MultimediaApplication"
operatingSystem="Any (Browser-based)"
/>
<BreadcrumbStructuredData
items={[
{ name: "Home", url: "/" },
{ name: "Tools", url: "/tools" },
{ name: "Video to Frames", url: "/tools/video-frames" },
]}
/>
{children}
</>
);
}

View File

@@ -73,6 +73,7 @@ export const metadata: Metadata = {
icons: {
icon: "/icon.svg",
},
manifest: "/manifest.json",
openGraph: {
type: "website",
siteName: "KYMR.TOP",

View File

@@ -5,56 +5,61 @@ interface ToolPage {
en: { title: string; description: string };
zh: { title: string; description: string };
lastModified: Date;
priority: number;
}
const tools: ToolPage[] = [
{
path: "/tools/image-compress",
en: {
title: "Image Compression - Optimize Images for Web & Mobile",
description: "Optimize images for web and mobile without quality loss. Support for batch processing and format conversion including PNG, JPEG, WebP.",
title: "Image Compression - Optimize PNG, JPEG, WebP Online Free",
description: "Free online image compressor. Optimize PNG, JPEG, WebP, AVIF images without quality loss. Batch processing, format conversion, browser-based.",
},
zh: {
title: "图片压缩 - 为网页和移动端优化图片",
description: "为网页和移动端优化图片,不影响质量。支持批量处理和格式转换,包括 PNG、JPEG、WebP。",
title: "图片压缩 - 免费在线优化 PNG、JPEG、WebP 图片",
description: "免费在线图片压缩工具。无损优化 PNG、JPEG、WebP、AVIF 图片。支持批量处理、格式转换,浏览器本地处理。",
},
lastModified: new Date("2025-01-01"),
lastModified: new Date("2026-02-08"),
priority: 0.9,
},
{
path: "/tools/video-frames",
en: {
title: "Video to Frame Sequence - Extract Frame Sequences from Videos",
description: "Extract frame sequences from videos with precision control. Support for MP4, WebM and other video formats. Export as PNG, WebP or ZIP.",
title: "Video to Frame Sequence - Extract Frames from Video Online Free",
description: "Free online video to frame sequence extractor. Extract PNG, WebP, JPEG frames from MP4, WebM, MOV videos with custom frame rates.",
},
zh: {
title: "视频转序列帧 - 从视频提取序列帧",
description: "精确控制从视频中提取序列帧。支持 MP4、WebM 等视频格式。导出为 PNG、WebP 或 ZIP。",
title: "视频转序列帧 - 免费在线从视频提取帧图片",
description: "免费在线视频转序列帧工具。从 MP4、WebM、MOV 视频中提取 PNG、WebP、JPEG 帧图片,可自定义帧率。",
},
lastModified: new Date("2025-01-01"),
lastModified: new Date("2026-02-08"),
priority: 0.9,
},
{
path: "/tools/audio-compress",
en: {
title: "Audio Compression - Compress & Convert Audio Files",
description: "Compress and convert audio files with ease. Support for MP3, WAV, OGG and more. Adjustable quality settings.",
title: "Audio Compression - Compress & Convert Audio Files Online Free",
description: "Free online audio compressor and converter. Compress MP3, WAV, OGG, AAC, FLAC files. Browser-based with no uploads required.",
},
zh: {
title: "音频压缩 - 压缩并转换音频文件",
description: "轻松压缩转换音频文件。支持 MP3、WAV、OGG 等格式。可调节质量设置。",
title: "音频压缩 - 免费在线压缩并转换音频文件",
description: "免费在线音频压缩转换工具。压缩 MP3、WAV、OGG、AAC、FLAC 文件。浏览器本地处理无需上传。",
},
lastModified: new Date("2025-01-01"),
lastModified: new Date("2026-02-08"),
priority: 0.8,
},
{
path: "/tools/texture-atlas",
en: {
title: "Texture Atlas Generator - Create Sprite Sheets Online",
description: "Generate texture atlases and sprite sheets for game development. Pack multiple sprites into a single texture atlas with JSON data export.",
title: "Texture Atlas Generator - Create Sprite Sheets Online Free",
description: "Free online texture atlas and sprite sheet generator for game development. Pack multiple sprites into optimized atlases with JSON data export.",
},
zh: {
title: "纹理图集生成器 - 在线创建精灵图",
description: "为游戏开发生成纹理图集和精灵图。将多个精灵打包到单个纹理图集中,支持导出 JSON 数据。",
title: "纹理图集生成器 - 免费在线创建精灵图",
description: "免费在线纹理图集和精灵图生成器。将多个精灵打包到优化的图集中,支持导出 JSON 数据。",
},
lastModified: new Date("2025-01-01"),
lastModified: new Date("2026-02-08"),
priority: 0.8,
},
];
@@ -65,14 +70,8 @@ export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
{
url: baseUrl,
lastModified: new Date(),
changeFrequency: "daily",
priority: 1,
},
{
url: `${baseUrl}/tools`,
lastModified: new Date(),
changeFrequency: "weekly",
priority: 0.9,
priority: 1,
},
];
@@ -80,7 +79,7 @@ export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
url: `${baseUrl}${tool.path}`,
lastModified: tool.lastModified,
changeFrequency: "weekly" as const,
priority: 0.8,
priority: tool.priority,
}));
return [...staticPages, ...toolPages];

View File

@@ -37,14 +37,6 @@ export function WebSiteStructuredData({ lang = "en" }: WebSiteProps) {
keywords:
"image compression, image converter, WebP converter, PNG optimizer, video converter, video to frame sequence, audio compression, texture atlas, sprite sheet generator, game development tools, browser-based tools",
inLanguage: "en-US",
potentialAction: {
"@type": "SearchAction",
target: {
"@type": "EntryPoint",
urlTemplate: `${baseUrl}/search?q={search_term_string}`,
},
"query-input": "required name=search_term_string",
},
},
zh: {
name: "KYMR.TOP",
@@ -155,3 +147,34 @@ export function SoftwareApplicationStructuredData({
/>
);
}
interface BreadcrumbItem {
name: string;
url: string;
}
interface BreadcrumbProps {
items: BreadcrumbItem[];
}
export function BreadcrumbStructuredData({ items }: BreadcrumbProps) {
const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || "https://kymr.top";
const data = {
"@context": "https://schema.org",
"@type": "BreadcrumbList",
itemListElement: items.map((item, index) => ({
"@type": "ListItem",
position: index + 1,
name: item.name,
item: `${baseUrl}${item.url}`,
})),
};
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }}
/>
);
}