Optymalizacja SEO wdrożenia SvelteKit: Adaptery, prerenderowanie i renderowanie na brzegu sieci

Adapter SvelteKit i ustawienia prerenderowania dla poszczególnych tras decydują o tym, gdzie i kiedy renderowane są Twoje strony — a to wpływa na TTFB, LCP i budżet indeksowania. Dogłębna analiza skupiona na wdrożeniu: wybór adapter-static/node/vercel/cloudflare/netlify, prerender = true/false/'auto', ograniczenia środowiska brzegowego oraz tworzenie sitemap.xml i robots.txt.

Opublikowano po raz pierwszy: 3 lip 2026 · Ostatnia aktualizacja: 3 sie 2026 · Advanced
Języki

Adapter SvelteKit i ustawienie prerenderowania dla poszczególnych tras decydują o tym, gdzie i kiedy strona jest renderowana — statyczny HTML w czasie budowania, SSR na serwerze lub SSR na brzegu sieci — a ta decyzja wpływa na TTFB, co przekłada się na LCP i zdolność indeksowania. Wybierz adapter-static dla czysto treściowych witryn, adapter node/vercel/cloudflare z prerenderowaniem dla poszczególnych tras w przypadku witryn mieszanych (treść plus aplikacja), a adapter brzegowy, gdy globalny TTFB ma znaczenie (akceptując zimne starty i brak Node fs). prerender = 'auto' to narzędzie dla witryn mieszanych. Środowiska brzegowe nie mogą czytać systemu plików. SvelteKit nie generuje sitemap.xml ani robots.txt — tworzysz je jako punkty końcowe +server.js, a strategia zależy od adaptera.

TL;DR — Adapter nie zmienia co renderuje SvelteKit — zmienia gdzie i kiedy: statycznie w czasie budowania (adapter-static), w czasie żądania na serwerze, który sam uruchamiasz (adapter-node), lub w czasie żądania na funkcjach serverless/edge (adapter-vercel/-netlify/-cloudflare). Per-route prerender = true buduje statyczny HTML i usuwa trasę z dynamicznego manifestu; prerender = 'auto' prerenderuje i pozostawia ją w manifeście — narzędzie dla mieszanych witryn /blog/[slug]. Środowiska edge działają na izolatach V8: brak Node fs, a zimne starty szkodzą TTFB, co wpływa na LCP i (według dokumentacji Google o budżecie indeksowania) na wydajność indeksowania. SvelteKit nie generuje żadnego sitemap.xml ani robots.txt — zbuduj je jako endpointy +server.js i pamiętaj, że strategia zależy od adaptera. To węższy, skoncentrowany na wdrożeniu towarzysz artykułu o podstawach SEO SvelteKit w tej sekcji; zakładam, że wiesz już, że SvelteKit domyślnie używa SSR i nie będę tego tutaj ponownie omawiał.

Jedna myśl, która wszystko wyjaśnia

Adapter nie zmienia tego, co jest renderowane. Zmienia gdzie i kiedy. To cała rzecz. Dokumentacja SvelteKit ujmuje to precyzyjnie: adaptery “take the built app as input and generate output for deployment.” Evidence for this claim SvelteKit adapters take the built application as input and generate deployment-specific output. Scope: Deployment output; adapter choice can still constrain supported runtime features. Confidence: high · Verified: SvelteKit: Adapters Twoje komponenty, Twoje funkcje load, Twoje metadane <svelte:head> — identyczne w każdym adapterze. Różni się tylko:

  • Kiedy HTML jest tworzony: w czasie budowania (statycznie/prerenderowany) lub w czasie żądania (SSR na serwerze, funkcji serverless lub funkcji edge).
  • Gdzie jest tworzony: na pojedynczym serwerze źródłowym, na regionalnej funkcji serverless lub w sieci edge blisko odwiedzającego.

Wszystko poniżej wynika z tych dwóch osi.

Dlaczego wybory dotyczące wdrożenia są wyborami SEO

Łańcuch jest krótki i dobrze udokumentowany: TTFB → LCP → wydajność indeksowania.

Czas do pierwszego bajtu to czas, w jakim host zaczyna wysyłać odpowiedź. Prerenderowany plik serwowany z pamięci podręcznej CDN ma TTFB bliski zeru. Serwer, który musi wyrenderować stronę, ma wyższy. Funkcja serverless lub edge z zimnym startem może mieć znacznie wyższy przy pierwszym trafieniu. TTFB jest bezpośrednim wejściem do Largest Contentful Paint — nie możesz namalować tego, czego nie otrzymałeś — a LCP to sygnał Core Web Vitals.

Strona indeksowania jest tam, gdzie Google jest najbardziej jednoznaczne. Z dokumentacji o budżecie indeksowania: “If the site responds quickly for a while, the limit goes up, meaning more connections can be used to crawl. If the site slows down or responds with server errors, the limit goes down and Google crawls less.” (tłumaczenie) „Jeśli witryna odpowiada szybko przez jakiś czas, limit rośnie, co oznacza, że można użyć więcej połączeń do indeksowania. Jeśli witryna zwalnia lub odpowiada błędami serwera, limit spada i Google indeksuje mniej.” A linia z najlepszymi praktykami: “Make your pages efficient to load. If Google can load and render your pages faster, we might be able to read more content from your site.” (tłumaczenie) „Spraw, aby Twoje strony ładowały się efektywnie. Jeśli Google może szybciej ładować i renderować Twoje strony, być może będziemy w stanie przeczytać więcej treści z Twojej witryny.” Funkcja edge z zimnym startem, która wolno odpowiada, podlega tej samej dynamice co wolny serwer źródłowy.

Jedna uwaga uczciwości na wstępie: Google nie publikuje żadnych wytycznych specyficznych dla SvelteKit. Nie ma dokumentu ani odcinka Search Off the Record wymieniającego adaptery SvelteKit, prerender = 'auto' ani zimne starty edge. To, co tutaj robię, to stosowanie ogólnych wytycznych Google dotyczących renderowania i budżetu indeksowania do specyficznych mechanizmów SvelteKit — a nie cytowanie przedstawiciela, który komentował SvelteKit, bo żaden tego nie zrobił. Ramy Google, że “server-side or pre-rendering is still a great idea because it makes your website faster for users and crawlers, and not all bots can run JavaScript” (tłumaczenie) „renderowanie po stronie serwera lub wstępne renderowanie to nadal świetny pomysł, ponieważ sprawia, że Twoja witryna jest szybsza dla użytkowników i robotów indeksujących, a nie wszystkie boty potrafią uruchamiać JavaScript” to najbliższa oficjalna kotwica i jest niezależna od frameworka.

Wybór adaptera pod kątem wyników SEO

adapter-auto — domyślny wybór bez konfiguracji i jego ograniczenia

Nowe projekty SvelteKit są dostarczane z adapter-auto. Wykrywa on platformę — Vercel, Netlify, Cloudflare Pages, Azure, AWS — i instaluje odpowiedni adapter w czasie budowania. To dobry punkt wyjścia, ale warto znać twardy sufit: adapter-auto nie przyjmuje żadnych opcji. W momencie, gdy potrzebujesz { edge: true }, powiązań Cloudflare, Vercel ISR lub jakiejkolwiek konfiguracji specyficznej dla platformy, instalujesz bezpośrednio bazowy adapter (adapter-vercel, adapter-cloudflare itd.). Traktuj auto jako szkielet, a nie decyzję produkcyjną.

adapter-static — pełny SSG, dla stron z treścią na pierwszym miejscu

adapter-static prerenderuje całą Twoją stronę do plików statycznych w czasie budowania. Żaden serwer nie działa; host serwuje płaski HTML. Evidence for this claim adapter-static prerenders a SvelteKit site as static files. Scope: Routes must be prerenderable; performance outcomes depend on hosting and page design. Confidence: high · Verified: SvelteKit: Static site generation Dla strony z treścią na pierwszym miejscu to najmocniejszy profil SEO, jaki możesz mieć — najniższy TTFB, brak zimnych startów, nic do awarii. Jedynym wymaganiem jest pułapka opisana szczegółowo w artykule o podstawach: SSR musi pozostać włączone podczas budowania, w przeciwnym razie otrzymasz puste skorupy zamiast wyrenderowanego HTML. Nie będę tego tutaj ponownie wyjaśniać poza zaznaczeniem tego.

Haczyk to sztywność. Wszystko, co naprawdę wymaga logiki serwera na żądanie (prawdziwe wyszukiwanie, treść per użytkownik, obsługa formularzy bez zewnętrznego punktu końcowego) nie może działać na czysto statycznej kompilacji — do tego właśnie służą kolejne adaptery.

adapter-node — serwer, który kontrolujesz

adapter-node tworzy samodzielny serwer Node.js. Uruchamiasz go, skalujesz go, Ty posiadasz TTFB. To najbardziej elastyczna opcja i ta z najmniejszą liczbą niespodzianek w czasie działania — pełne API Node, w tym fs. To dobry wybór, gdy masz już infrastrukturę, potrzebujesz bibliotek Node, których nie mogą uruchomić środowiska brzegowe, lub chcesz przewidywalnych (niezimnych) czasów odpowiedzi z ciepłego serwera. Kompromis to operacyjność: uruchamiasz serwer, a jego szybkość i dostępność stają się teraz Twoją przepustowością indeksowania.

adapter-vercel — serverless, edge i ISR

adapter-vercel domyślnie wdraża na funkcje serverless Vercel, z kilkoma istotnymi dla SEO dźwigniami ustawianymi per trasa przez export const config:

  • runtime: 'edge' przenosi tę trasę do środowiska brzegowego Vercel (więcej poniżej).
  • regions kontroluje, gdzie działają funkcje serverless — bliżej Twoich użytkowników (lub Twojej bazy danych) oznacza niższe opóźnienia.
  • isr włącza Incremental Static Regeneration: isr: { expiration: 60 } serwuje buforowany zasób statyczny i regeneruje go po oknie, dając “przewagę wydajności i kosztów prerenderowanej treści z elastycznością dynamicznie renderowanej treści.” ISR to prawdziwa czwarta ścieżka między czysto statycznym a czysto SSR — ale zauważ zastrzeżenie samych dokumentów: “Użycie ISR na trasie z export const prerender = true nie będzie miało efektu, ponieważ trasa jest prerenderowana w czasie budowania.” ISR i prerender to alternatywy, a nie opcje do układania.

adapter-cloudflare — Workers/Pages, globalne edge

adapter-cloudflare celuje w Cloudflare Workers i Pages — SSR w globalnej sieci brzegowej, często najniższy TTFB dla geograficznie rozproszonej publiczności. Ważnym ograniczeniem jest środowisko uruchomieniowe: Workers działają na izolatach V8, nie Node. Z dokumentacji: “Nie możesz używać fs w Cloudflare Workers.” Niektóre API Node działają tylko za flagą zgodności nodejs_compat, a nawet wtedy wsparcie nie jest jeden do jednego. Jeśli czytałeś pliki w czasie żądania (mapa przekierowań, plik danych, dane wejściowe dla niestandardowych obrazów OG), ten kod wymaga przemyślenia — omówione w sekcji o edge poniżej.

(Starszy adapter-cloudflare-workers jest przestarzały; nowe projekty używają adapter-cloudflare, który obsługuje zarówno Workers, jak i Pages. Jeśli jesteś na starym, migracja jest zalecaną ścieżką.)

adapter-netlify — funkcje lub Edge Functions (Deno)

adapter-netlify domyślnie wdraża do funkcji Node Netlify lub do Edge Functions opartych na Deno z edge: true. Ten sam kształt co Vercel: domyślnie serverless z opcją edge. Jedna uwaga specyficzna dla SvelteKit — Netlify Forms wymaga, aby strona formularza była prerenderowana, aby Netlify mógł wykryć znaczniki formularza w czasie wdrażania, co jest małym wymogiem „prerenderuj tę trasę” nałożonym na dodatek do wyboru adaptera.

Decyzja w jednym zdaniu każda

  • Czysta strona treściowaadapter-static, prerenderuj wszystko.
  • Strona treściowa z dynamicznymi fragmentamiadapter-node/-vercel/-cloudflare, prerender = true na treści, false/'auto' na trasach dynamicznych.
  • Aplikacja/pulpit z personalizacją → SSR-first (node lub edge), prerenderuj tylko statyczną powłokę (marketing, logowanie).
  • Globalna, wrażliwa na TTFB publiczność → adapter edge dla tras dynamicznych, akceptując ograniczenia Node-API i rzeczywistość zimnego startu.

(Zakładka Decision Tree przedstawia to jako przepływ rozgałęziony.)

Strategia prerenderowania dla stron mieszanych

Co faktycznie robią true / false / 'auto'

export const prerender to opcja strony per-route (lub per-layout), a trzy wartości to nie tylko włącz/wyłącz:

  • true — zbuduj tę trasę do statycznego HTML w czasie budowania. Kluczowe jest to, że jest „wykluczona z manifestów używanych do dynamicznego SSR, co sprawia, że twój serwer (lub funkcje serverless/edge) jest mniejszy.” Po prerenderowaniu trasa nie może wrócić do dynamicznego renderowania — jest statyczna, kropka.
  • false — zawsze renderuj na żądanie. Brak pliku statycznego.
  • 'auto' — narzędzie dla stron mieszanych. Prerenderuje trasę i utrzymuje ją w dynamicznym manifeście serwera, więc ta sama trasa może być serwowana statycznie dla znanych ścieżek i renderowana serwerowo dla reszty. To jest zbudowane dokładnie dla przypadku, który opisuje dokumentacja: trasa taka jak /blog/[slug] „gdzie chcesz prerenderować swoją najnowszą/popularną treść, ale serwerowo renderować długi ogon.”

Ponieważ prerenderowane trasy zmniejszają pakiet serwera, strona w większości prerenderowana z kilkoma trasami 'auto'/false wdraża mniejszą, tańszą, szybszą funkcję — wydajnościowa wygrana niezależna od SEO.

Trasy dynamiczne wymagają funkcji entries

Crawler prerenderowania odkrywa strony, podążając za linkami <a> z twoich punktów wejścia. To działa dla tras statycznych, ale trasa dynamiczna taka jak /blog/[slug] nie ma stałego URL, który crawler mógłby znaleźć. Jeśli nic nie linkuje do danego sluga, SvelteKit nie będzie wiedział, że istnieje — i trafisz na klasyczny błąd budowania, że trasy „były oznaczone jako prerenderowalne, ale nie zostały prerenderowane.”

Rozwiązaniem jest jawna funkcja entries (lub config.kit.prerender.entries), która wymienia wartości parametrów:

// src/routes/blog/[slug]/+page.server.js
export const prerender = true;

export function entries() {
  return [
    { slug: 'hello-world' },
    { slug: 'sveltekit-deployment-seo' },
  ];
}

W praktyce generujesz tę listę z CMS lub katalogu treści. Bez niej prerenderowanie obejmuje tylko slugi, które crawler linków przypadkiem znajdzie.

Wzorzec /blog/[slug] w praktyce

Połącz te dwa elementy i masz kanoniczną konfigurację strony mieszanej: prerender = 'auto' plus funkcja entries, która zwraca twoje najnowsze i popularne posty. Te otrzymują statyczny HTML w czasie budowania; wszystko, czego nie ma na liście, przechodzi do SSR na żądanie. Nowe posty renderują się dynamicznie, aż następne budowanie je prerenderuje. To pragmatyczny środek między „prerenderuj wszystkie 40 000 postów przy każdym budowaniu” a „renderuj każdy post przy każdym żądaniu.”

Ograniczenia środowiska edge wpływające na SEO

config.runtime = 'edge' jest per-route (na Vercel)

Edge to nie przełącznik wszystko-albo-nic. Na Vercel to opcja strony per-route:

// +page.server.js or +server.js
export const config = { runtime: 'edge' };

To oznacza, że możesz wypchnąć trasy o wysokim ruchu i podlegające cache na edge dla niskiego TTFB, jednocześnie utrzymując trasy zależne od Node na standardowym serverless (Node) runtime w tym samym wdrożeniu. Mieszaj świadomie.

Brak fs, brak dowolnych API Node

Środowiska edge — Cloudflare Workers, Vercel Edge Functions, Netlify’s Deno Edge Functions — nie zapewniają Node’owego fs. Dokumentacja Cloudflare: “You can’t use fs in Cloudflare Workers.” Vercel: “You can’t use fs in edge functions.” Obie wskazują na te same dwa wyjścia awaryjne: użyj pomocnika read z $app/server, aby uzyskać dostęp do dołączonych zasobów, lub “prerender the routes in question”, aby dostęp do plików odbywał się w czasie budowania, a nie w czasie żądania.

Przypadki związane z SEO, w których to boli: dynamiczne generowanie obrazów OG, które czyta plik czcionki lub szablonu, mapy przekierowań oparte na plikach lub punkt końcowy mapy witryny, który czyta treść z dysku. Każdy z nich albo przenosi się do read() z $app/server, albo przenosi się do czasu prerenderowania/budowania. To nie jest bloker — to ograniczenie “wiedz, zanim wybierzesz edge”.

Zimne starty i TTFB — kiedy edge pomaga, a kiedy nie

Funkcje edge nadal mają zimne starty. Zimna funkcja edge przy pierwszym żądaniu może być

  • wolniejsza * niż ciepły serwer Node i znacznie wolniejsza niż prerenderowany plik serwowany z pamięci podręcznej. Edge wygrywa, gdy funkcja pozostaje ciepła lub gdy jest sparowana z agresywnym buforowaniem, aby większość żądań w ogóle nie trafiała do funkcji. To nie jest automatycznie najszybsza opcja — “wdrożenie na edge” nie jest synonimem “szybciej.” W przypadku witryny treściowej prerenderowane statyczne wyjście bije edge SSR pod względem TTFB za każdym razem, ponieważ nie ma funkcji do uruchomienia.

Generowanie sitemap.xml i robots.txt (SvelteKit tego nie zrobi)

To jest luka, którą większość poradników SvelteKit pomija, a większość audytów wyłapuje. SvelteKit generuje żadnego sitemap.xml i żadnego robots.txt automatycznie — niezależnie od adaptera, niezależnie od tego, ile stron prerenderujesz. W pełni statyczna witryna z tysiącami prerenderowanych stron nadal nie ma mapy witryny, chyba że ją zbudujesz.

Wzorzec punktu końcowego +server.js

Idiomatyczna mapa witryny to punkt końcowy trasy, który zwraca XML z odpowiednim Content-Type:

// src/routes/sitemap.xml/+server.js
export const prerender = true; // needed on adapter-static

export async function GET() {
  const urls = await getAllUrls(); // from your CMS/content
  const body = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${urls.map((u) => `  <url><loc>${u}</loc></url>`).join('\n')}
</urlset>`;

  return new Response(body, {
    headers: { 'Content-Type': 'application/xml' },
  });
}

Strategia zależy od Twojego adaptera

Oto część, która spina cały ten artykuł: Twoja strategia mapy witryny jest zależna od wyboru adaptera.

  • Na adapter-static, punkt końcowy mapy witryny potrzebuje export const prerender = true, aby został uwzględniony w statycznym wyjściu — nie ma serwera w czasie działania, który generowałby go na żądanie. Jest wypiekany w czasie budowania, co oznacza, że jest tylko tak świeży, jak Twoja ostatnia kompilacja.
  • Na adapterze Node/serverless/edge, ten sam punkt końcowy może generować mapę witryny dynamicznie na żądanie z Twojego CMS lub bazy danych — zawsze aktualna, bez potrzeby przebudowy. (Na adapterze edge pamiętaj o ograniczeniu fs: pobieraj URL-e z API lub binding, a nie z odczytu dysku.)

Więc pytanie “czy moja mapa witryny powinna być statyczna czy dynamiczna?” nie jest osobną decyzją — wynika z adaptera, który już wybrałeś.

robots.txt: plik statyczny vs. punkt końcowy

Dwie opcje. Umieść zwykły robots.txt w folderze static/ (serwowany automatycznie pod /robots.txt), co jest najprostszym wyborem i wystarcza dla większości witryn. Lub wygeneruj go z punktu końcowego src/routes/robots.txt/+server.js, gdy potrzebujesz, aby różnił się w zależności od środowiska (blokowanie robotów na staging, zezwalanie im w produkcji, na przykład). W każdym razie nie blokuj pakietu /_app/ ani CSS — to psuje renderowanie silnikom, które renderują.

Jeśli podchodzisz do tego z szerszej perspektywy frameworka lub JavaScript-SEO, logika “gdzie i kiedy odbywa się renderowanie” jest tutaj tą samą logiką, która rządzi JavaScript SEO ogólnie, a artykuł o podstawach SvelteKit w tej sekcji omawia tryby renderowania i wzorce metadanych, na których opiera się ten artykuł.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.