Web TippsUse custom web fonts in Google Sheets charts(08.09.2026 um 17:05 Uhr)
Web TippsIntroducing the new 1Password App for Google Chat(08.09.2026 um 18:02 Uhr)
Web TippsUse custom web fonts in Google Sheets charts(08.09.2026 um 17:05 Uhr)
Web TippsIntroducing the new 1Password App for Google Chat(08.09.2026 um 18:02 Uhr)

🔧 Programmierung 🕛 vor 5 Monaten 5 Min Lesezeit
0

Three Tiers of Data Freshness in a SvelteKit Static Site

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

Ahnii!



Static sites are fast and cheap to host, but your data goes stale the moment you deploy. This post shows how a .






The Setup



The site uses SvelteKit with API using a +page.server.ts loader. This runs only at build time because the page is prerendered.




CODE
// src/routes/+page.server.ts
export async function load({ fetch }) {
let northCloudArticles = [];
try {
northCloudArticles = await fetchNorthCloudFeed(fetch, 'pipeline', 6);
} catch {
// Feed optional on homepage
}
return { northCloudArticles };
}






The data is baked into the HTML. It updates when you deploy, not when the API changes. This is fine for a homepage showcase where articles from yesterday are still relevant.






Tier 2: Cached Client-Side



The blog page fetches an external RSS feed at runtime in the browser. The service layer caches results for 30 minutes.




CODE
// src/lib/services/blog-service.ts
const FEED_URL = 'https://jonesrussell.github.io/blog/feed.xml';
const CACHE_DURATION = 1000 * 60 * 30; // 30 minutes

export const fetchFeed = async (
fetchFn: typeof fetch,
{ page = 1, pageSize = 5 } = {}
) => {
const cacheKey = `blog-feed-cache-${page}-${pageSize}`;
const cached = feedCache.getCache(cacheKey);

if (cached) {
return {
items: cached.data.slice((page - 1) * pageSize, page * pageSize),
hasMore: cached.data.length > page * pageSize
};
}

const response = await fetchFn(FEED_URL);
const posts = parseXMLFeed(await response.text());
feedCache.updateCache(cacheKey, posts);

return {
items: posts.slice((page - 1) * pageSize, page * pageSize),
hasMore: posts.length > page * pageSize
};
};






The blog page itself has prerender = false, so there's no static HTML for it. When you navigate to /blog, GitHub Pages serves the SPA fallback, and SvelteKit loads the RSS feed client-side. New blog posts appear within 30 minutes without a redeploy.






Tier 3: Prerendered With Live Refresh



Series pages combine prerendering with live data. They're statically generated at build time (good for SEO), but on client-side navigation they fetch fresh data from the Hugo JSON endpoint and live source code from GitHub.




CODE
// src/routes/blog/series/[id]/+page.ts
export const prerender = true;

export async function entries() {
const response = await fetch(SERIES_JSON_URL);
const data = await response.json();
return data.series.map((s) => ({ id: s.id }));
}

export const load: PageLoad = async ({ params }) => {
const series = await fetchSeries(globalThis.fetch, params.id);
// Fetches companion code from raw.githubusercontent.com
const allEntries = series.groups.flatMap((g) => g.entries);
const codeResults = await Promise.all(
allEntries.map((entry) =>
fetchSeriesCode(globalThis.fetch, repoSlug, entry.companionFiles ?? [])
)
);
return { series, codeResults };
};






The entries() function tells SvelteKit which series IDs exist at build time, so each one gets a prerendered HTML page. The load function runs both at build time (for prerendering) and at runtime (on client-side navigation), so the data is always current when you browse.






The Fetch Injection Pattern



Every service takes fetchFn: typeof fetch as its first parameter instead of using the global fetch directly.




CODE
export async function fetchSeries(
fetchFn: typeof fetch,
id: string
): Promise<Series | null> {
const index = await fetchSeriesIndex(fetchFn);
return index.series.find((s) => s.id === id) ?? null;
}






This matters because SvelteKit provides its own fetch wrapper during SSR and prerendering that handles cookies, relative URLs, and request deduplication. By accepting fetch as a parameter, the same service works during prerendering (with SvelteKit's fetch) and at runtime (with the browser's fetch). It also makes testing straightforward since you can pass a mock fetch.



One caveat: during prerendering, SvelteKit's fetch wrapper can fail on cross-origin requests. For external APIs, use globalThis.fetch in the loader instead.






What Goes Stale and When






































Data source Freshness Updates when
North Cloud feed Frozen at deploy Next GitHub Pages deploy
Blog RSS 30-min cache Cache expires, page revisited
Series JSON Live on navigation Every client-side page load
GitHub source code Live on navigation Every client-side page load
Markdown resources Frozen at deploy Next GitHub Pages deploy


The tradeoff is intentional. Homepage data can be a day old. Blog posts need to appear within 30 minutes. Series companion code should always reflect the latest commit.






Avoiding the 404 Flash



If you use prerender = false on a route, GitHub Pages has no HTML file for that URL. It serves a 404 before the SPA fallback kicks in. The page still renders correctly for users, but search engines see the 404 status code, and there's a brief flash of the fallback page.



The fix for any route with known paths: use prerender = true with an entries() function that returns all valid slugs. This gives you static HTML for the initial load (SEO-friendly, no 404) while still fetching fresh data on client-side navigation.



For routes where the slugs aren't known at build time (like the blog listing), prerender = false with SPA fallback is the right choice. Just know the SEO tradeoff.



Baamaapii

Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
3 Quellen
Use custom web fonts in Google Sheets charts
2 Quellen
Introducing the new 1Password App for Google Chat
1 Quelle
Context-aware access controls are available for Gemini Enterprise in the Admin console
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Three Tiers of Data Freshness in a SvelteKit Static Site

Thematisch verwandte Begriffe: Three, Tiers, Data, Freshness · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...