Référencement
L’aspect le plus important du référencement (SEO] est la création de contenu de qualité largement cité par d’autres ressources sur le web. Toutefois, il y a quelques considérations techniques permettant de créer des sites qui performent bien à ce niveau.
Clé-en-main
SSR
Même si les moteurs de recherche se sont améliorés depuis quelques années dans l’indexation de
contenu rendu avec du code JavaScript côté client, le contenu rendu sur le serveur est indexé plus
souvent et plus efficacement. SvelteKit utilise le SSR par défaut, et bien que vous puissiez le
désactiver dans le hook handle
, vous devriez le laisser activé à
moins que n’ayez une bonne raison de ne pas le faire.
Le rendu de SvelteKit est très configurable et vous pouvez implémenter du rendu dynamique si nécessaire. Ce n’est généralement pas recommandé, puisque le SSR offre d’autres avantages que le référencement.
Performance
Des indicateurs comme les Core Web Vitals impactent le classment d’une page par les moteurs de recherche. Puisque Svelte et SvelteKit introduisent une surcouche minimale, il est plus facile de créer des sites de haute performance. Vous pouvez tester les performances de votre site en utilisant les outils de Google PageSpeed Insights ou Lighthouse. Lisez la page sur les performances pour plus de détails.
URLs normalisées
SvelteKit redirige les chemins ayant des trailing slashes vers des chemins n’en ayant pas (ou inversement selon votre configuration), car les URLs dupliquées détériorent le référencement.
Mise en place manuelle
<title> et <meta>
Chaque page devrait avoir des éléments <title>
et <meta name="description">
uniques et bien
écrits dans un élément <svelte:head>
. Des conseils sur comment écrire des
titres et descriptions pertinentes, en plus d’autres suggestions sur comment rendre votre contenu
compréhensible par les moteurs de recherche, sont disponibles dans la documentation Lighthouse SEO
audits.
Un usage commun est de renvoyer les
data
concernant le référencement depuis vos fonctionsload
, puis de les utiliser (en tant quepage.data
) dans l’élément<svelte:head>
de votre layout racine.
Sitemaps
export async function function GET(): Promise<Response>
GET() {
return new var Response: new (body?: BodyInit | null, init?: ResponseInit) => Response
This Fetch API interface represents the response to a request.
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"
>
<!-- les éléments <url> se déclarent ici -->
</urlset>`.String.trim(): string
Removes the leading and trailing white space and line terminator characters from a string.
trim(),
{
ResponseInit.headers?: HeadersInit | undefined
headers: {
'Content-Type': 'application/xml'
}
}
);
}
AMP
Une réalité malheureuse du développement web moderne est qu’il est quelques fois nécessaire de créer
une version Accelerated Mobile Pages (AMP) de votre site. SvelteKit vous permet
de le faire en définissant l’option inlineStyleThreshold
...
/** @type {import('@sveltejs/kit').Config} */
const const config: {
kit: {
inlineStyleThreshold: number;
};
}
config = {
kit: {
inlineStyleThreshold: number;
}
kit: {
// puisque <link rel="stylesheet"> n'est pas
// autorisé, inliner tous les styles
inlineStyleThreshold: number
inlineStyleThreshold: var Infinity: number
Infinity
}
};
export default const config: {
kit: {
inlineStyleThreshold: number;
};
}
config;
..., en désactivant l’option csr
de vos fichiers +layout.js
/ +layout.server.js
...
export const const csr: false
csr = false;
..., en ajoutant amp
à votre fichier app.html
...
<html amp>
...
..., et en transformant le HTML utilisant l’option transformPageChunk
avec transform
importé
depuis @sveltejs/amp
:
import * as import amp
amp from '@sveltejs/amp';
/** @type {import('@sveltejs/kit').Handle} */
export async function function handle({ event, resolve }: {
event: any;
resolve: any;
}): Promise<any>
handle({ event: any
event, resolve: any
resolve }) {
let let buffer: string
buffer = '';
return await resolve: any
resolve(event: any
event, {
transformPageChunk: ({ html, done }: {
html: any;
done: any;
}) => string | undefined
transformPageChunk: ({ html: any
html, done: any
done }) => {
let buffer: string
buffer += html: any
html;
if (done: any
done) return import amp
amp.function transform(html: string): string
transform(let buffer: string
buffer);
}
});
}
import * as import amp
amp from '@sveltejs/amp';
import type { type Handle = (input: {
event: RequestEvent;
resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>;
}) => MaybePromise<...>
The handle
hook runs every time the SvelteKit server receives a request and
determines the response.
It receives an event
object representing the request and a function called resolve
, which renders the route and generates a Response
.
This allows you to modify response headers or bodies, or bypass SvelteKit entirely (for implementing routes programmatically, for example).
Handle } from '@sveltejs/kit';
export const const handle: Handle
handle: type Handle = (input: {
event: RequestEvent;
resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>;
}) => MaybePromise<...>
The handle
hook runs every time the SvelteKit server receives a request and
determines the response.
It receives an event
object representing the request and a function called resolve
, which renders the route and generates a Response
.
This allows you to modify response headers or bodies, or bypass SvelteKit entirely (for implementing routes programmatically, for example).
Handle = async ({ event: RequestEvent<Partial<Record<string, string>>, string | null>
event, resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>
resolve }) => {
let let buffer: string
buffer = '';
return await resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>
resolve(event: RequestEvent<Partial<Record<string, string>>, string | null>
event, {
ResolveOptions.transformPageChunk?: ((input: {
html: string;
done: boolean;
}) => MaybePromise<string | undefined>) | undefined
Applies custom transforms to HTML. If done
is true, it’s the final chunk. Chunks are not guaranteed to be well-formed HTML
(they could include an element’s opening tag but not its closing tag, for example)
but they will always be split at sensible boundaries such as %sveltekit.head%
or layout/page components.
transformPageChunk: ({ html: string
html, done: boolean
done }) => {
let buffer: string
buffer += html: string
html;
if (done: boolean
done) return import amp
amp.function transform(html: string): string
transform(let buffer: string
buffer);
}
});
};
To prevent shipping any unused CSS as a result of transforming the page to amp, we can use dropcss
:
import * as import amp
amp from '@sveltejs/amp';
import module "dropcss"
dropcss from 'dropcss';
/** @type {import('@sveltejs/kit').Handle} */
export async function function handle(input: {
event: RequestEvent;
resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>;
}): MaybePromise<...>
handle({ event: RequestEvent<Partial<Record<string, string>>, string | null>
event, resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>
resolve }) {
let let buffer: string
buffer = '';
return await resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>
resolve(event: RequestEvent<Partial<Record<string, string>>, string | null>
event, {
ResolveOptions.transformPageChunk?: ((input: {
html: string;
done: boolean;
}) => MaybePromise<string | undefined>) | undefined
Applies custom transforms to HTML. If done
is true, it’s the final chunk. Chunks are not guaranteed to be well-formed HTML
(they could include an element’s opening tag but not its closing tag, for example)
but they will always be split at sensible boundaries such as %sveltekit.head%
or layout/page components.
transformPageChunk: ({ html: string
html, done: boolean
done }) => {
let buffer: string
buffer += html: string
html;
if (done: boolean
done) {
let let css: string
css = '';
const const markup: string
markup = import amp
amp
.function transform(html: string): string
transform(let buffer: string
buffer)
.String.replace(searchValue: string | RegExp, replaceValue: string): string (+3 overloads)
Replaces text in a string, using a regular expression or search string.
replace('⚡', 'amp') // dropcss ne peut pas gérer ce caractère
.String.replace(searchValue: {
[Symbol.replace](string: string, replacer: (substring: string, ...args: any[]) => string): string;
}, replacer: (substring: string, ...args: any[]) => string): string (+3 overloads)
Replaces text in a string, using an object that supports replacement within a string.
replace(/<style amp-custom([^>]*?)>([^]+?)<\/style>/, (match: string
match, attributes: any
attributes, contents: any
contents) => {
let css: string
css = contents: any
contents;
return `<style amp-custom${attributes: any
attributes}></style>`;
});
let css: string
css = module "dropcss"
dropcss({ css: string
css, html: string
html: const markup: string
markup }).css;
return const markup: string
markup.String.replace(searchValue: string | RegExp, replaceValue: string): string (+3 overloads)
Replaces text in a string, using a regular expression or search string.
replace('</style>', `${let css: string
css}</style>`);
}
}
});
}
import * as import amp
amp from '@sveltejs/amp';
import module "dropcss"
dropcss from 'dropcss';
import type { type Handle = (input: {
event: RequestEvent;
resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>;
}) => MaybePromise<...>
The handle
hook runs every time the SvelteKit server receives a request and
determines the response.
It receives an event
object representing the request and a function called resolve
, which renders the route and generates a Response
.
This allows you to modify response headers or bodies, or bypass SvelteKit entirely (for implementing routes programmatically, for example).
Handle } from '@sveltejs/kit';
export const const handle: Handle
handle: type Handle = (input: {
event: RequestEvent;
resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>;
}) => MaybePromise<...>
The handle
hook runs every time the SvelteKit server receives a request and
determines the response.
It receives an event
object representing the request and a function called resolve
, which renders the route and generates a Response
.
This allows you to modify response headers or bodies, or bypass SvelteKit entirely (for implementing routes programmatically, for example).
Handle = async ({ event: RequestEvent<Partial<Record<string, string>>, string | null>
event, resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>
resolve }) => {
let let buffer: string
buffer = '';
return await resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>
resolve(event: RequestEvent<Partial<Record<string, string>>, string | null>
event, {
ResolveOptions.transformPageChunk?: ((input: {
html: string;
done: boolean;
}) => MaybePromise<string | undefined>) | undefined
Applies custom transforms to HTML. If done
is true, it’s the final chunk. Chunks are not guaranteed to be well-formed HTML
(they could include an element’s opening tag but not its closing tag, for example)
but they will always be split at sensible boundaries such as %sveltekit.head%
or layout/page components.
transformPageChunk: ({ html: string
html, done: boolean
done }) => {
let buffer: string
buffer += html: string
html;
if (done: boolean
done) {
let let css: string
css = '';
const const markup: string
markup = import amp
amp
.function transform(html: string): string
transform(let buffer: string
buffer)
.String.replace(searchValue: string | RegExp, replaceValue: string): string (+3 overloads)
Replaces text in a string, using a regular expression or search string.
replace('⚡', 'amp') // dropcss ne peut pas gérer ce caractère
.String.replace(searchValue: {
[Symbol.replace](string: string, replacer: (substring: string, ...args: any[]) => string): string;
}, replacer: (substring: string, ...args: any[]) => string): string (+3 overloads)
Replaces text in a string, using an object that supports replacement within a string.
replace(/<style amp-custom([^>]*?)>([^]+?)<\/style>/, (match: string
match, attributes: any
attributes, contents: any
contents) => {
let css: string
css = contents: any
contents;
return `<style amp-custom${attributes: any
attributes}></style>`;
});
let css: string
css = module "dropcss"
dropcss({ css: string
css, html: string
html: const markup: string
markup }).css;
return const markup: string
markup.String.replace(searchValue: string | RegExp, replaceValue: string): string (+3 overloads)
Replaces text in a string, using a regular expression or search string.
replace('</style>', `${let css: string
css}</style>`);
}
}
});
};
C’est une bonne idée d’utiliser le hook
handle
pour valider le HTML transformé en utilisantamphtml-validator
, mais uniquement si vous pré-rendez vos pages, car ce traitement est très lent.
Modifier cette page sur Github llms.txt