最佳实践
SEO
在 GitHub 上编辑此页面SEO 最重要的方面是创建高质量的内容,并使其在网络上被广泛链接。但是,对于构建排名靠前的网站,有一些技术上的注意事项。
开箱即用永久链接
SSR永久链接
虽然近年来搜索引擎在索引使用客户端 JavaScript 渲染的内容方面做得更好,但服务器端渲染的内容被索引得更频繁、更可靠。SvelteKit 默认采用 SSR,虽然你可以在 handle
中禁用它,但除非你有充分的理由,否则你应该保留它。
SvelteKit 的渲染具有高度可配置性,你可以在必要时实现 动态渲染。通常不建议这样做,因为 SSR 除了 SEO 之外还有其他好处。
性能永久链接
诸如 核心网络指标 等信号会影响搜索引擎排名。由于 Svelte 和 SvelteKit 引入的开销很小,因此构建高性能网站变得更加容易。你可以使用 Google 的 PageSpeed Insights 或 Lighthouse 来测试网站的性能。阅读 性能页面 了解更多详情。
规范化 URL永久链接
SvelteKit 将带有尾部斜杠的路径名重定向到不带尾部斜杠的路径名(或根据你的配置反之亦然),因为重复的 URL 对 SEO 不利。
手动设置永久链接
<title> 和 <meta>永久链接
每个页面都应该在 <svelte:head>
内有编写良好的、唯一的 <title>
和 <meta name="description">
元素。有关如何编写描述性标题和描述的指导,以及其他有关使搜索引擎能够理解内容的建议,请参阅 Google 的Lighthouse SEO 审核文档。
一种常见模式是从页面
load
函数返回与 SEO 相关的data
,然后在根布局的<svelte:head>
中将其用作(作为$page.data
)。
站点地图永久链接
站点地图有助于搜索引擎优先考虑网站中的页面,尤其是在内容量大的情况下。你可以使用端点动态创建站点地图
ts
export async functionGET () {return newResponse (`<?xml version="1.0" encoding="UTF-8" ?><urlsetxmlns="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'}});}
ts
export async functionGET () {return newResponse (`<?xml version="1.0" encoding="UTF-8" ?><urlsetxmlns="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永久链接
现代 Web 开发的一个不幸现实是,有时有必要创建网站的加速移动页面 (AMP)版本。在 SvelteKit 中,可以通过设置inlineStyleThreshold
选项来完成此操作...
ts
/** @type {import('@sveltejs/kit').Config} */constconfig = {kit : {// since <link rel="stylesheet"> isn't// allowed, inline all stylesinlineStyleThreshold :Infinity }};export defaultconfig ;
...在根 +layout.js
/+layout.server.js
中禁用 csr
...
ts
export constcsr = false;
ts
export constcsr = false;
...向 app.html
添加 amp
<html amp>
...
...并使用从 @sveltejs/amp
导入的 transform
以及 transformPageChunk
转换 HTML
ts
import * asamp from '@sveltejs/amp';/** @type {import('@sveltejs/kit').Handle} */export async functionhandle ({event ,resolve }) {letbuffer = '';return awaitresolve (event , {transformPageChunk : ({html ,done }) => {buffer +=html ;if (done ) returnamp .transform (buffer );}});}
ts
import * asamp from '@sveltejs/amp';import type {Handle } from '@sveltejs/kit';export consthandle :Handle = async ({event ,resolve }) => {letbuffer = '';return awaitresolve (event , {transformPageChunk : ({html ,done }) => {buffer +=html ;if (done ) returnamp .transform (buffer );},});};
为了防止因将页面转换为 amp 而发送任何未使用的 CSS,我们可以使用dropcss
ts
import * asamp from '@sveltejs/amp';importCannot find module 'dropcss' or its corresponding type declarations.2307Cannot find module 'dropcss' or its corresponding type declarations.dropcss from'dropcss' ;/** @type {import('@sveltejs/kit').Handle} */export async functionhandle ({event ,resolve }) {letbuffer = '';return awaitresolve (event , {transformPageChunk : ({html ,done }) => {buffer +=html ;if (done ) {letcss = '';constmarkup =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 ;returnmarkup .replace ('</style>', `${css }</style>`);}}});}
ts
import * asamp from '@sveltejs/amp';importCannot find module 'dropcss' or its corresponding type declarations.2307Cannot find module 'dropcss' or its corresponding type declarations.dropcss from'dropcss' ;import type {Handle } from '@sveltejs/kit';export consthandle :Handle = async ({event ,resolve }) => {letbuffer = '';return awaitresolve (event , {transformPageChunk : ({html ,done }) => {buffer +=html ;if (done ) {letcss = '';constmarkup =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 ;returnmarkup .replace ('</style>', `${css }</style>`);}},});};
最好使用
handle
钩子来使用amphtml-validator
验证转换后的 HTML,但仅在你预渲染页面时使用,因为它非常慢。