如何在 Nuxt.js 中获得 Stack Overflow SEO 友好的 URL 结构?
How to get Stack Overflow SEO friendly URL structure in Nuxt.js?
Stack Overflow 具有以下 URL 结构 whosebug.com/questions/{question ID}/{question title}
,如果您输入错误 {question title}
,您将被永久重定向 301
到正确的 URL只要你有正确的 {question ID}
.
假设我同时拥有 id
和 slug
,我如何制作与 Stack Overflow 在 Nuxt.js
和 [=19] 中相同的 URL 结构=]?
编辑:显然 URL 结构被称为 Clean URL。
我试过使用完全动态的 URLs 和 pages/x/_.vue
,但这为我的每个请求提供了一个“新”页面,并且没有提供 301 重定向。
This post 建议如下:/questions/8811192/question-title
可以重写为 /mywebsite.php?id=8811192&convention=questions
。因此,如果我可以将 /qeustions/{id}/{title}
解释为只是 /qeustions/{id}
,我想我可能已经完成了一半。
以下对我有用,但我不确定它是否与 Stack Overflow URL 结构的工作方式完全相同。
我正在使用 async asyncData
从数据库中获取内容,您可以访问
context 和 redirect
、req
和 res
作为参数,您可以执行 301
重定向。
首先,我在我的文件夹中使用 unknown dynamic nested routes,就像这样 /pages/folder/_.vue
。这将捕获所有路线,包括 domain.com/folder/{id}
和 domain.com/folder/{id}/{title}
.
要在请求的 url 中获取 ID,您可以拆分 pathMatch 并获取第一个元素,例如 params.pathMatch.split('/')[0]
.
然后我使用id从数据库中获取内容,在我的例子中是Strapi。像这样 await $strapi.findOne('contentType', id)
.
之后我们可以像这样 /folder/${data.id}/${data.slug}
创建我们想要的实际 URL。注意:data.slug
可以替换为 data.title
,后者可以转换为 URL 友好字符串。
最后我们可以匹配用户请求的URL和内容if(route.fullPath !== actualURL)
的实际URL,如果请求的url不一样我们可以执行redirect(301, actualURL)
.
的重定向
我的全部代码:
async asyncData({ redirect, req, route, app, $strapi, error, params }) {
try {
const recipeID = params.pathMatch.split('/')[0];
const matchingRecipe = await $strapi.findOne('recipes', recipeID);
const correctPath = `${app.localePath('recipes')}/${matchingRecipe.id}/${matchingRecipe.slug}`;
if(route.fullPath !== correctPath) {
console.log(`Redirect: ${route.fullPath} => ${correctPath}`);
redirect(301, correctPath);
}
return {
recipe: matchingRecipe
}
} catch(e) {
console.log(e)
error({ statusCode: e.statusCode, message: e.original });
}
},
Stack Overflow 具有以下 URL 结构 whosebug.com/questions/{question ID}/{question title}
,如果您输入错误 {question title}
,您将被永久重定向 301
到正确的 URL只要你有正确的 {question ID}
.
假设我同时拥有 id
和 slug
,我如何制作与 Stack Overflow 在 Nuxt.js
和 [=19] 中相同的 URL 结构=]?
编辑:显然 URL 结构被称为 Clean URL。
我试过使用完全动态的 URLs 和 pages/x/_.vue
,但这为我的每个请求提供了一个“新”页面,并且没有提供 301 重定向。
This post 建议如下:/questions/8811192/question-title
可以重写为 /mywebsite.php?id=8811192&convention=questions
。因此,如果我可以将 /qeustions/{id}/{title}
解释为只是 /qeustions/{id}
,我想我可能已经完成了一半。
以下对我有用,但我不确定它是否与 Stack Overflow URL 结构的工作方式完全相同。
我正在使用 async asyncData
从数据库中获取内容,您可以访问
context 和 redirect
、req
和 res
作为参数,您可以执行 301
重定向。
首先,我在我的文件夹中使用 unknown dynamic nested routes,就像这样 /pages/folder/_.vue
。这将捕获所有路线,包括 domain.com/folder/{id}
和 domain.com/folder/{id}/{title}
.
要在请求的 url 中获取 ID,您可以拆分 pathMatch 并获取第一个元素,例如 params.pathMatch.split('/')[0]
.
然后我使用id从数据库中获取内容,在我的例子中是Strapi。像这样 await $strapi.findOne('contentType', id)
.
之后我们可以像这样 /folder/${data.id}/${data.slug}
创建我们想要的实际 URL。注意:data.slug
可以替换为 data.title
,后者可以转换为 URL 友好字符串。
最后我们可以匹配用户请求的URL和内容if(route.fullPath !== actualURL)
的实际URL,如果请求的url不一样我们可以执行redirect(301, actualURL)
.
我的全部代码:
async asyncData({ redirect, req, route, app, $strapi, error, params }) {
try {
const recipeID = params.pathMatch.split('/')[0];
const matchingRecipe = await $strapi.findOne('recipes', recipeID);
const correctPath = `${app.localePath('recipes')}/${matchingRecipe.id}/${matchingRecipe.slug}`;
if(route.fullPath !== correctPath) {
console.log(`Redirect: ${route.fullPath} => ${correctPath}`);
redirect(301, correctPath);
}
return {
recipe: matchingRecipe
}
} catch(e) {
console.log(e)
error({ statusCode: e.statusCode, message: e.original });
}
},