最重要的 SEO 方面是创建高质量的内容,这些内容在网络上被广泛链接。然而,对于构建排名良好的网站,还有一些技术考虑因素。 ## 即开即用 ### SSR 尽管近年来搜索引擎在索引使用客户端 JavaScript 渲染的内容方面有所改进,但服务器端渲染的内容索引得更频繁且更可靠。SvelteKit 默认采用 SSR(服务器端渲染),尽管你可以在`handle`中禁用它,除非你有充分的理由不这样做,否则你应该保持开启状态。 > \[!注意\] SvelteKit 的渲染高度可配置,您如果需要可以实施 [动态渲染](https://developers.google.com/search/docs/advanced/javascript/dynamic-rendering)。通常不推荐这样做,因为 SSR 除了 SEO 之外还有其他好处。 ### 性能 信号如[核心网页关键指标](https://web.dev/vitals/#core-web-vitals)影响搜索引擎排名。由于 Svelte 和 SvelteKit 引入的额外开销最小,因此构建高性能网站更容易。您可以使用 Google 的[页面速度洞察](https://pagespeed.web.dev/)或[灯塔](https://developers.google.com/web/tools/lighthouse)测试您网站的性能。阅读[性能页面](performance)获取更多详细信息。 ### 标准化 URL SvelteKit 将带有尾随斜杠的路径名重定向到不带斜杠的路径名(或反之亦然,具体取决于您的[配置](page-options#trailingSlash)),因为重复的 URL 对 SEO 不利。 ## 手动设置 ### <标题> 和 <元数据> 每页都应该包含编写良好且独特的 `` 和 `<meta name="description">` 元素,这些元素位于 [`<svelte:head>`](../svelte/svelte-head) 内。有关如何编写描述性标题和描述的指南,以及如何使内容更容易被搜索引擎理解的其它建议,可以在 Google 的 [Lighthouse SEO audits](https://web.dev/lighthouse-seo/) 文档中找到。 > \[!注意\] 常见的模式是从页面 [`加载`](load) 函数返回与 SEO 相关的 `数据`,然后将其(作为 [`page.data`]($app-state))用于根 [布局](routing#layout) 中的 `<svelte:head>`。 ### 网站地图 [网站地图](https://developers.google.com/search/docs/advanced/sitemaps/build-sitemap)帮助搜索引擎优先处理您网站内的页面,尤其是当您有大量内容时。您可以使用端点动态创建网站地图。 ```js /// file: src/routes/sitemap.xml/+server.js export async function GET() { return new Response( ` <?xml version="1.0" encoding="UTF-8" ?> <urlset xmlns="https://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="https://www.w3.org/1999/xhtml" xmlns:mobile="https://www.google.com/schemas/sitemap-mobile/1.0" xmlns:news="https://www.google.com/schemas/sitemap-news/0.9" xmlns:image="https://www.google.com/schemas/sitemap-image/1.1" xmlns:video="https://www.google.com/schemas/sitemap-video/1.1" > <!-- <url> elements go here --> </urlset>`.trim(), { headers: { 'Content-Type': 'application/xml' } } ); } ``` ### AMP 现代网页开发的一个不幸现实是,有时有必要创建一个[加速移动页面(AMP)](https://amp.dev/)版本的网站。在 SvelteKit 中,可以通过设置[`inlineStyleThreshold`](configuration#inlineStyleThreshold)选项来完成此操作... ```js /// file: svelte.config.js /** @type {import('@sveltejs/kit').Config} */ const config = { kit: { // since <link rel="stylesheet"> isn't // allowed, inline all styles inlineStyleThreshold: Infinity } }; export default config; ``` ...在您的根目录 `csr` 中禁用 `+layout.js`/`+layout.server.js`... ```js /// file: src/routes/+layout.server.js export const csr = false; ``` ...将`amp`添加到您的`app.html`中 `<html amp> ...` ...并使用 `transformPageChunk` 和从 `@sveltejs/amp` 导入的 `transform` 对 HTML 进行转换: ```js /// file: src/hooks.server.js import * as amp from '@sveltejs/amp'; /** @type {import('@sveltejs/kit').Handle} */ export async function handle({ event, resolve }) { let buffer = ''; return await resolve(event, { transformPageChunk: ({ html, done }) => { buffer += html; if (done) return amp.transform(buffer); } }); } ``` 为防止在将页面转换为 amp 时发送任何未使用的 CSS,我们可以使用[`dropcss`](https://www.npmjs.com/package/dropcss): ```js // @filename: ambient.d.ts declare module 'dropcss'; // @filename: index.js // ---cut--- /// file: src/hooks.server.js // @errors: 2307 import * as amp from '@sveltejs/amp'; import dropcss from 'dropcss'; /** @type {import('@sveltejs/kit').Handle} */ export async function handle({ event, resolve }) { let buffer = ''; return await resolve(event, { transformPageChunk: ({ html, done }) => { buffer += html; if (done) { let css = ''; const markup = amp .transform(buffer) .replace('⚡', 'amp') // dropcss can't handle this character .replace(/<style amp-custom([^>]*?)>([^]+?)<\/style>/, (match, attributes, contents) => { css = contents; return `<style amp-custom${attributes}></style>`; }); css = dropcss({ css, html: markup }).css; return markup.replace('</style>', `${css}</style>`); } } }); } ``` > \[!注意\] 使用 `handle` 钩子来验证转换后的 HTML 使用 `amphtml-validator` 是一个好主意,但仅当你在预渲染页面时,因为它非常慢。