From 7a11e80c3801f8b31573fa08eb5f0190215332e9 Mon Sep 17 00:00:00 2001
From: caorushizi <84996057@qq.com>
Date: Sun, 17 May 2026 23:00:30 +0800
Subject: [PATCH] feat: use next image optimization for docs templates
---
apps/docs/next.config.mjs | 10 +++----
.../src/components/template-cover-image.tsx | 27 +++++++++++++++++++
.../components/template-example-detail.tsx | 14 ++++++----
.../src/components/template-examples-list.tsx | 6 +++--
apps/docs/vercel.json | 3 +--
vercel.json | 3 +--
6 files changed, 47 insertions(+), 16 deletions(-)
create mode 100644 apps/docs/src/components/template-cover-image.tsx
diff --git a/apps/docs/next.config.mjs b/apps/docs/next.config.mjs
index 5293f14..2b38307 100644
--- a/apps/docs/next.config.mjs
+++ b/apps/docs/next.config.mjs
@@ -1,15 +1,15 @@
+import { fileURLToPath } from "node:url";
import { createMDX } from "fumadocs-mdx/next";
const withMDX = createMDX();
+const workspaceRoot = fileURLToPath(new URL("../..", import.meta.url));
/** @type {import('next').NextConfig} */
const config = {
- // SSG: 全静态导出,交给 Vercel 作为静态 Next.js 文档站托管。
- output: "export",
- // Vercel 的 Output Directory 指向 apps/docs/dist。
+ // Keep build artifacts under apps/docs/dist while letting Vercel run the
+ // managed Next.js runtime, including the Image Optimization API.
distDir: "dist",
- // SSG 模式下 next/image 默认依赖 server,关掉优化用原图。
- images: { unoptimized: true },
+ outputFileTracingRoot: workspaceRoot,
// 让生成的 URL 与 Starlight 的 trailing-slash 行为一致。
trailingSlash: true,
reactStrictMode: true,
diff --git a/apps/docs/src/components/template-cover-image.tsx b/apps/docs/src/components/template-cover-image.tsx
new file mode 100644
index 0000000..5bcffbe
--- /dev/null
+++ b/apps/docs/src/components/template-cover-image.tsx
@@ -0,0 +1,27 @@
+import Image, { type ImageProps } from "next/image";
+
+type TemplateCoverImageProps = Omit<
+ ImageProps,
+ "alt" | "fill" | "height" | "src" | "width"
+> & {
+ src: string;
+ alt?: string;
+ sizes: string;
+};
+
+export function TemplateCoverImage({
+ src,
+ sizes,
+ alt = "",
+ ...props
+}: TemplateCoverImageProps) {
+ return (
+
+ );
+}
diff --git a/apps/docs/src/components/template-example-detail.tsx b/apps/docs/src/components/template-example-detail.tsx
index 028c3f9..d90dfad 100644
--- a/apps/docs/src/components/template-example-detail.tsx
+++ b/apps/docs/src/components/template-example-detail.tsx
@@ -20,6 +20,7 @@ import { getTemplateById } from "@/data/templates";
import { TemplateExamplesNav } from "@/components/template-examples-nav";
import { CustomTemplateModal } from "@/components/custom-template-modal";
import { PresetCreateCommandDialog } from "@/components/preset-create-command-dialog";
+import { TemplateCoverImage } from "@/components/template-cover-image";
import {
shouldInterceptClick,
useViewTransitionNavigate,
@@ -138,13 +139,15 @@ export function TemplateExampleDetail({
-
@@ -257,10 +260,11 @@ function RelatedCard({
style={{ viewTransitionName: `example-card-${example.id}` }}
>
-
diff --git a/apps/docs/src/components/template-examples-list.tsx b/apps/docs/src/components/template-examples-list.tsx
index 1a02843..6dd88a6 100644
--- a/apps/docs/src/components/template-examples-list.tsx
+++ b/apps/docs/src/components/template-examples-list.tsx
@@ -17,6 +17,7 @@ import { examples, type Example, type ExampleCategory } from "@/data/examples";
import { TemplateExamplesNav } from "@/components/template-examples-nav";
import { CustomTemplateModal } from "@/components/custom-template-modal";
import { PresetCreateCommandDialog } from "@/components/preset-create-command-dialog";
+import { TemplateCoverImage } from "@/components/template-cover-image";
import {
shouldInterceptClick,
useViewTransitionNavigate,
@@ -253,10 +254,11 @@ function ExampleCard({
style={{ viewTransitionName: cardTransitionName }}
>
-
diff --git a/apps/docs/vercel.json b/apps/docs/vercel.json
index 376789a..f08a459 100644
--- a/apps/docs/vercel.json
+++ b/apps/docs/vercel.json
@@ -1,9 +1,8 @@
{
"$schema": "https://openapi.vercel.sh/vercel.json",
- "framework": null,
+ "framework": "nextjs",
"installCommand": "pnpm install --frozen-lockfile",
"buildCommand": "pnpm build",
- "outputDirectory": "dist",
"headers": [
{
"source": "/install.sh",
diff --git a/vercel.json b/vercel.json
index 69f0da8..40e5263 100644
--- a/vercel.json
+++ b/vercel.json
@@ -1,9 +1,8 @@
{
"$schema": "https://openapi.vercel.sh/vercel.json",
- "framework": null,
+ "framework": "nextjs",
"installCommand": "pnpm --dir apps/docs install --frozen-lockfile",
"buildCommand": "pnpm --dir apps/docs build",
- "outputDirectory": "apps/docs/dist",
"headers": [
{
"source": "/install.sh",