静かな森

静かな森

致虚极,守静笃。

马上订阅 静かな森 RSS 更新: https://innei.ren/feed

Next.js + Vite,这是什么新的操作?

Innei
2025年6月14日 23:16
该渲染由 Shiro API 生成,可能存在排版问题,最佳体验请前往:https://innei.in/posts/Z-Turn/nextjs%2Bvite-hack-combined

事情是这样的。

前段日子做了一个摄影佬必备的线上图库。

https://github.com/Afilmory/Afilmory

这个项目是 Vite + React 写的,当初没有考虑要做 SEO 的打算。

然后想给 /:photoId 路由加个 Open Graph 的支持。那必须得上一个 Server 了。

那用什么呢,不管用什么必须的支持 Serverless,毕竟我也不想多开一个服务器去托管了。

现在支持 Serverless 的太多,hono,fastify 都可以。我最后还是选择了 Next.js。一开始只想着它处理和画 OG 最方便,而且可以直接托管到 Cloudflare Pages 上。

目前,已知我的 app 是 SPA,vite build 之后是静态产物。我需要在 Next.js 上托管这些静态产物。

托管静态产物,这还不简单。我直接一个 vite build && cp -r dist ../ssr/public 。放到 public 下就被 Next.js 自动托管了。

但是,index.html 的 <head /> 咋办,vite build 出来的都是死的。

我直接用 dom 操作替换一下。

import { DOMParser } from 'linkedom'

export const runtime = 'edge'

export const GET = async (
  request: NextRequest,
  { params }: { params: Promise<{ photoId: string }> },
) 
  try {
    const indexHtml = await fetch(new URL('./index.html', import.meta.url)).then(r => r.text())
    const document = new DOMParser().parseFromString(indexHtml, 'text/html')

    // Remove all twitter meta tags and open graph meta tags
    document.head.childNodes.forEach((node) => {
      if (node.nodeName === 'META') {
        const $meta = node as HTMLMetaElement
        if ($meta.getAttribute('name')?.startsWith('twitter:')) {
          $meta.remove()
        }
        if ($meta.getAttribute('property')?.startsWith('og:')) {
          $meta.remove()
        }
      }
    })
    // Insert meta open graph tags and twitter meta tags
    createAndInsertOpenGraphMeta(document, photo, request)

    return new Response(document.documentElement.outerHTML, {
      headers: {
        'Content-Type': 'text/html',
        'X-SSR': '1',
      },
    })
  } catch (error) {
    console.error('Error generating SSR page:', error)
    console.info('Falling back to static index.html')
    console.info(error.message)

    return new Response(indexHtml, {
      headers: { 'Content-Type': 'text/html' },
      status:...

剩余内容已隐藏

查看完整文章以阅读更多