Sapper 中如何正确处理动态路由参数的缺失情况?

Top丶红娟 阅读 3

我在 Sapper 里用动态路由 [slug].svelte,但用户直接访问 /article 而不是 /article/123 时,页面就白屏了。我试过在 preload 里判断 params.slug 是否存在,但好像没生效,控制台还报错说 Cannot read property ‘slug’ of undefined。

有没有办法在路由参数缺失时自动重定向到 404 页面?或者至少优雅地处理这种情况?

export async function preload(page, session) {
  const { slug } = page.params;
  if (!slug) {
    // 这里该怎么跳转到 404?
  }
  // ...
}
我来解答 赞 1 收藏
二维码
手机扫码查看
1 条解答
司徒瑞瑞
这个问题其实有点坑,Sapper 的动态路由匹配规则是:访问 /article 时,它优先匹配 article.svelte(如果存在),而不是 [slug].svelte。所以你那个动态路由文件根本没被加载,page.params 当然是 undefined。

如果你想让 /article 和 /article/123 都走同一个 [slug].svelte 文件,得用 Sapper 的可选参数语法:

把文件名改成 [[slug]].svelte(双中括号表示可选),这样 /article 和 /article/123 都会匹配到这个路由。

然后在 preload 里这样处理:

export async function preload(page, session) {
const { slug } = page.params;

if (!slug) { this.redirect(301, '/404');
return;
}

// 继续你的业务逻辑
}


this.redirect() 是 Sapper 提供的方式,第一个参数是状态码,第二个是路径。

如果你没有把文件改成可选参数的形式,而是想让 /article 直接报 404,那更简单的做法是:删除 article.svelte,只保留 [slug].svelte,然后访问 /article 时 Sapper 会自动返回 404。

还有一种情况是你在组件里直接用了 $page.params.slug 但没先判断,这种也会白屏。确保在模板里用 {$page.params.slug} 之前先检查存不存在,或者用 export let data; 配合 preload 传过来的数据来判断。

官方文档里关于路由匹配优先级那部分可以看一下,讲得挺细的。
点赞
2026-03-13 06:00