You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SvelteKit中通过[slug]参数加载HTML页面内容?

SvelteKit加载本地HTML文件内容的正确方式

项目结构

src
  lib
    cms
      projects
        slug1.html
        slug2.html
  routes
    projects
      [slug]
        +page.server.js
        +page.svelte

需求:用户访问https://example.com/projects/slug1时,加载对应slug1.html的内容并展示在页面中。

错误代码与报错信息

你之前在+page.server.js中写的代码:

/** @type {import ('./$types').PageServerLoad } */
export async function load({ params }) {
  console.log(params);
  return {
    project: await import(`../../../lib/cms/projects/${params.slug}.html?raw`),
  };
}

尝试在+page.svelte中用{@html data.project}展示时,出现如下报错:

Error: Data returned from `load` while rendering /projects/[slug] is not serializable: Cannot stringify POJOs with symbolic keys (data.project)
    at get_data (/Users/me/Documents/Repositories/site/node_modules/@sveltejs/kit/src/runtime/server/page/render.js:592:9)
    at Module.render_response (/Users/me/Documents/Repositories/site/node_modules/@sveltejs/kit/src/runtime/server/page/render.js:264:27)
    at async Module.render_page (/Users/me/Documents/Repositories/site/node_modules/@sveltejs/kit/src/runtime/server/page/index.js:286:10)
    at async resolve (/Users/me/Documents/Repositories/site/node_modules/@sveltejs/kit/src/runtime/server/respond.js:446:18)
    at async Module.respond (/Users/me/Documents/Repositories/site/node_modules/@sveltejs/kit/src/runtime/server/respond.js:319:20)
    at async file:///Users/me/Documents/Repositories/site/node_modules/@sveltejs/kit/src/exports/vite/dev/index.js:524:22

问题根源

用import加载带?raw后缀的文件时,返回的是一个模块对象(而非纯文本字符串),这个对象包含Symbol类型的键,而SvelteKit要求load函数返回的数据必须是可序列化的(能转换为JSON格式),这类带Symbol键的对象无法被序列化,因此触发了报错。

正确解决方案

在+page.server.js中直接用Node.js的文件系统模块读取HTML文件内容,因为+page.server.js运行在服务器端,拥有文件系统访问权限:

修改后的+page.server.js代码

import { readFile } from 'node:fs/promises';
import { join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { error } from '@sveltejs/kit';

/** @type {import ('./$types').PageServerLoad } */
export async function load({ params }) {
  // 获取当前文件所在目录的绝对路径
  const __dirname = fileURLToPath(new URL('.', import.meta.url));
  // 拼接HTML文件的绝对路径
  const filePath = join(__dirname, '../../../lib/cms/projects', `${params.slug}.html`);

  try {
    // 读取文件内容为字符串
    const projectContent = await readFile(filePath, 'utf8');
    return { project: projectContent };
  } catch (err) {
    // 如果文件不存在,抛出404错误
    throw error(404, 'Project not found');
  }
}

+page.svelte中的用法

保持原来的写法即可:

<script>
  /** @type {import('./$types').PageData} */
  export let data;
</script>

{@html data.project}

说明

  • 使用readFile直接读取文件内容,返回的是纯字符串,完全符合SvelteKit的序列化要求。
  • 通过fileURLToPath和join拼接绝对路径,避免了相对路径在不同环境下的问题。
  • 增加了错误捕获,当请求的slug对应的HTML文件不存在时,返回404页面,提升用户体验。

内容的提问来源于stack exchange,提问作者Nicholas Pappas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 23:43:19