feat: SEO, PWA, and performance optimizations

- Add sitemap.xml endpoint and update robots.txt for SEO - Improve
manifest.json with richer metadata and categories - Add meta tags for
social sharing and accessibility - Preload critical assets and fonts for
faster loading - Optimize login background image and resource hints -
Enhance service worker for better caching strategies - Add security
headers to server responses - Update Vite config for chunking and
dependency optimization - Add logboek.md for project tracking
This commit is contained in:
2025-10-07 14:26:41 +02:00
parent 5f0cae604d
commit 716c05c256
15 changed files with 458 additions and 17 deletions

View File

@@ -14,6 +14,20 @@
<svelte:head>
<link rel="icon" href={favicon} />
<!-- Performance optimizations -->
<link
rel="preload"
href="/fonts/Washington.ttf"
as="font"
type="font/ttf"
crossorigin="anonymous"
/>
<link rel="dns-prefetch" href="//tile.openstreetmap.org" />
<link rel="preconnect" href="https://tile.openstreetmap.org" crossorigin="anonymous" />
<!-- Resource hints for login page background -->
{#if isLoginRoute}
<link rel="preload" href="/cafe-bg-compressed.jpg" as="image" />
{/if}
</svelte:head>
<Toaster />

View File

@@ -2,6 +2,26 @@
import { Map } from '$lib';
</script>
<svelte:head>
<title>Serengo - Meet the Unexpected</title>
<meta
name="description"
content="Discover unexpected places and experiences with Serengo's interactive map. Find hidden gems and explore your surroundings like never before."
/>
<meta property="og:title" content="Serengo - Meet the Unexpected" />
<meta
property="og:description"
content="Discover unexpected places and experiences with Serengo's interactive map. Find hidden gems and explore your surroundings like never before."
/>
<meta property="og:type" content="website" />
<meta name="twitter:card" content="summary" />
<meta name="twitter:title" content="Serengo - Meet the Unexpected" />
<meta
name="twitter:description"
content="Discover unexpected places and experiences with Serengo's interactive map. Find hidden gems and explore your surroundings like never before."
/>
</svelte:head>
<div class="home-container">
<main class="main-content">
<div class="map-section">

View File

@@ -5,6 +5,26 @@
let { form }: { form: ActionData } = $props();
</script>
<svelte:head>
<title>Login - Serengo</title>
<meta
name="description"
content="Sign in to your Serengo account to access personalized maps and discover unexpected places around you."
/>
<meta property="og:title" content="Login - Serengo" />
<meta
property="og:description"
content="Sign in to your Serengo account to access personalized maps and discover unexpected places around you."
/>
<meta property="og:type" content="website" />
<meta name="twitter:card" content="summary" />
<meta name="twitter:title" content="Login - Serengo" />
<meta
name="twitter:description"
content="Sign in to your Serengo account to access personalized maps and discover unexpected places around you."
/>
</svelte:head>
<div class="login-background flex min-h-svh flex-col items-center justify-center gap-6 p-6 md:p-10">
<div class="flex w-full max-w-sm flex-col gap-6">
<LoginForm {form} />
@@ -12,7 +32,7 @@
<style>
.login-background {
background-image: url('/cafe-bg.jpeg');
background-image: url('/cafe-bg-compressed.jpg');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
@@ -34,5 +54,16 @@
position: relative;
z-index: 2;
}
/* Preload hint for faster loading */
@media (prefers-reduced-data: no-preference) {
.login-background::after {
content: '';
position: absolute;
background-image: url('/cafe-bg-compressed.jpg');
opacity: 0;
z-index: -1;
}
}
</style>
</div>

View File

@@ -0,0 +1,29 @@
import type { RequestHandler } from '@sveltejs/kit';
export const GET: RequestHandler = async ({ url }) => {
const baseUrl = url.origin;
const lastmod = new Date().toISOString().split('T')[0]; // YYYY-MM-DD format
const sitemap = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>${baseUrl}/</loc>
<lastmod>${lastmod}</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>${baseUrl}/login</loc>
<lastmod>${lastmod}</lastmod>
<changefreq>monthly</changefreq>
<priority>0.5</priority>
</url>
</urlset>`;
return new Response(sitemap, {
headers: {
'Content-Type': 'application/xml',
'Cache-Control': 'max-age=86400' // Cache for 24 hours
}
});
};