Hash Routing
1. Import der Svelte Stores
import { derived, writable } from 'svelte/store';
writable
: Ein reaktiver Zustand, der direkt verändert werden kann.derived
: Ein abgeleiteter Zustand, der basierend auf anderen Stores berechnet wird.
2. Definition der createUrlStore
Funktion
export function createUrlStore(ssrUrl) {
- Diese Funktion erstellt einen Store, der die aktuelle URL der Seite speichert.
ssrUrl
: Wird genutzt, um beim Server-Side Rendering (SSR) eine URL vorzugeben, da es im SSR-Modus keinwindow
-Objekt gibt.
3. Fallunterscheidung: SSR oder Client-seitig
if (typeof window === 'undefined') {
const { subscribe } = writable(ssrUrl);
return { subscribe };
}
- Falls die Funktion im Server-Side Rendering ausgeführt wird (
typeof window === 'undefined'
):- Es wird ein
writable
Store mit der übergebenenssrUrl
erstellt. - Nur die
subscribe
-Methode des Stores wird zurückgegeben, da im SSR-Modus keine URL-Änderungen möglich sind.
- Es wird ein
4. Client-seitiger Modus
Wenn window
verfügbar ist (also im Browser), wird der Store für die URL erstellt:
a) Erstellung eines writable
Stores für die aktuelle URL
const href = writable(window.location.href);
href
: Speichert die aktuelle URL (window.location.href
) als Zustand.
b) Überschreiben der History-Methoden
const originalPushState = history.pushState;
const originalReplaceState = history.replaceState;
history.pushState = function () {
originalPushState.apply(this, arguments);
updateHref();
};
history.replaceState = function () {
originalReplaceState.apply(this, arguments);
updateHref();
};
pushState
undreplaceState
sind Methoden derhistory
-API, um die URL zu ändern, ohne die Seite neu zu laden.- Der Code überschreibt diese Methoden, sodass nach jeder URL-Änderung
updateHref()
aufgerufen wird.
c) Definieren von updateHref
const updateHref = () => href.set(window.location.href);
- Diese Funktion aktualisiert den
href
-Store mit der aktuellen URL.
d) Ereignislistener für Navigation
window.addEventListener('popstate', updateHref);
window.addEventListener('hashchange', updateHref);
popstate
: Wird ausgelöst, wenn der Benutzer über den Zurück- oder Vorwärts-Button im Browser navigiert.hashchange
: Wird ausgelöst, wenn sich der Hash in der URL ändert (z. B. von#section1
zu#section2
).
5. Rückgabe eines abgeleiteten Stores
return {
subscribe: derived(href, ($href) => new URL($href)).subscribe
};
- Es wird ein abgeleiteter Store zurückgegeben, der die
href
-URL (window.location.href
) in einURL
-Objekt umwandelt:new URL($href)
: Macht die URL besser nutzbar, z. B. für Abfragen wieurl.pathname
,url.searchParams
, etc.
6. Standard-Export
export default createUrlStore();
- Hier wird die Funktion ausgeführt und das Ergebnis (der URL-Store) direkt als Standard-Export bereitgestellt.
Wie wird das verwendet?
-
Importieren des Stores:
import urlStore from './path/to/store';
-
Abonnieren des Stores in einer Komponente:
<script>
import urlStore from './path/to/store';
let currentUrl;
const unsubscribe = urlStore.subscribe((url) => {
currentUrl = url;
});
</script>
<p>Aktuelle URL: {currentUrl.href}</p>urlStore.subscribe
liefert das aktuelleURL
-Objekt.- Du kannst z. B.
currentUrl.pathname
odercurrentUrl.searchParams
verwenden.
Vorteile:
- Zentralisiert die Verwaltung der aktuellen URL.
- Reaktiv: Änderungen an der URL werden automatisch in Svelte-Komponenten reflektiert.
- Nützlich für SPAs, die auf Änderungen in der URL reagieren müssen, z. B. für Routing oder Tracking.
Svelte 5-Konformität
-
Kompatibilität von Stores:
writable
undderived
sind auch in Svelte 5 vorhanden und funktionieren genauso wie in Svelte 3/4.- Die Nutzung von
subscribe
bleibt unverändert.
-
Unterschiede in Reactivity: In Svelte 5 kannst du Stores direkt mit dem
@
-Operator verwenden, wodurch die manuelle Nutzung vonsubscribe
in den meisten Fällen entfällt. Der Store muss dafür jedoch diesubscribe
-Methode implementieren (was hier der Fall ist).Beispiel mit dem Store:
<script>
import urlStore from './path/to/store';
</script>
<p>Aktuelle URL: {@urlStore.href}</p>Das funktioniert mit dem bestehenden Store, da er korrekt als Svelte-Store implementiert ist (er besitzt eine
subscribe
-Methode).
Optimierungen für Svelte 5
Obwohl der Store funktioniert, könnten wir ihn anpassen, um von neuen Features in Svelte 5 zu profitieren:
Optimierung: Automatische Dereferenzierung
In Svelte 5 kannst du direkt auf die Inhalte eines Stores zugreifen, indem du @
verwendest. Damit das reibungslos funktioniert, sollte die Rückgabe des Stores sauber und präzise gestaltet sein.
Anpassung:
return derived(href, ($href) => new URL($href));
- Statt ein Objekt mit
{ subscribe }
zurückzugeben, wird direkt der abgeleitete Store zurückgegeben.
Das hat zwei Vorteile:
- Der Store wird einfacher und klarer.
- Er ist direkt kompatibel mit der neuen Svelte-5-Syntax.
Vollständiger, angepasster Store
Hier ist der aktualisierte Code, optimiert für Svelte 5:
import { derived, writable } from 'svelte/store';
export function createUrlStore(ssrUrl) {
if (typeof window === 'undefined') {
return writable(new URL(ssrUrl));
}
const href = writable(window.location.href);
const originalPushState = history.pushState;
const originalReplaceState = history.replaceState;
const updateHref = () => href.set(window.location.href);
history.pushState = function () {
originalPushState.apply(this, arguments);
updateHref();
};
history.replaceState = function () {
originalReplaceState.apply(this, arguments);
updateHref();
};
window.addEventListener('popstate', updateHref);
window.addEventListener('hashchange', updateHref);
return derived(href, ($href) => new URL($href));
}
export default createUrlStore();
Verwendung in Svelte 5
Direkter Zugriff mit @
:
<script>
import urlStore from './path/to/store';
</script>
<p>Aktuelle URL: {@urlStore.href}</p>
<p>Pfad: {@urlStore.pathname}</p>
Nutzung in reaktiven Statements:
<script>
import urlStore from './path/to/store';
</script>
{#if @urlStore.pathname === '/home'}
<p>Willkommen auf der Startseite!</p>
{/if}
Zusammenfassung:
- Der ursprüngliche Store ist mit Svelte 5 kompatibel, da er die grundlegenden Store-Schnittstellen (
subscribe
) implementiert. - Durch eine kleine Anpassung (direkte Rückgabe eines abgeleiteten Stores) wird er noch einfacher und passt perfekt zu den neuen Features wie dem
@
-Operator. - Der optimierte Code verbessert die Lesbarkeit und den Workflow bei der Nutzung in Svelte 5.
Optimierungen für Svelte 5
Obwohl der Store funktioniert, könnten wir ihn anpassen, um von neuen Features in Svelte 5 zu profitieren:
Optimierung: Automatische Dereferenzierung
In Svelte 5 kannst du direkt auf die Inhalte eines Stores zugreifen, indem du @
verwendest. Damit das reibungslos funktioniert, sollte die Rückgabe des Stores sauber und präzise gestaltet sein.
Anpassung:
return derived(href, ($href) => new URL($href));
- Statt ein Objekt mit
{ subscribe }
zurückzugeben, wird direkt der abgeleitete Store zurückgegeben.
Das hat zwei Vorteile:
- Der Store wird einfacher und klarer.
- Er ist direkt kompatibel mit der neuen Svelte-5-Syntax.
Vollständiger, angepasster Store
Hier ist der aktualisierte Code, optimiert für Svelte 5:
import { derived, writable } from 'svelte/store';
export function createUrlStore(ssrUrl) {
if (typeof window === 'undefined') {
return writable(new URL(ssrUrl));
}
const href = writable(window.location.href);
const originalPushState = history.pushState;
const originalReplaceState = history.replaceState;
const updateHref = () => href.set(window.location.href);
history.pushState = function () {
originalPushState.apply(this, arguments);
updateHref();
};
history.replaceState = function () {
originalReplaceState.apply(this, arguments);
updateHref();
};
window.addEventListener('popstate', updateHref);
window.addEventListener('hashchange', updateHref);
return derived(href, ($href) => new URL($href));
}
export default createUrlStore();
Verwendung in Svelte 5
Direkter Zugriff mit @
:
<script>
import urlStore from './path/to/store';
</script>
<p>Aktuelle URL: {@urlStore.href}</p>
<p>Pfad: {@urlStore.pathname}</p>
Nutzung in reaktiven Statements:
<script>
import urlStore from './path/to/store';
</script>
{#if @urlStore.pathname === '/home'}
<p>Willkommen auf der Startseite!</p>
{/if}
Zusammenfassung:
- Der ursprüngliche Store ist mit Svelte 5 kompatibel, da er die grundlegenden Store-Schnittstellen (
subscribe
) implementiert. - Durch eine kleine Anpassung (direkte Rückgabe eines abgeleiteten Stores) wird er noch einfacher und passt perfekt zu den neuen Features wie dem
@
-Operator. - Der optimierte Code verbessert die Lesbarkeit und den Workflow bei der Nutzung in Svelte 5.
Einen URL-Wechsel in einer Svelte-Anwendung zu triggern, hängt davon ab, ob du eine vollständige Seitenaktualisierung (Page Reload) durchführen möchtest oder nur den URL ändern willst, ohne die Seite neu zu laden. Hier sind die wichtigsten Methoden:
1. URL ändern ohne Neuladen (Single-Page Application)
Wenn du nur die URL ändern möchtest, ohne die Seite neu zu laden, kannst du die history.pushState
- oder history.replaceState
-Methoden der Browser-API verwenden. Diese Methoden ändern die URL im Browser, ohne dass die Seite neu geladen wird.
Beispiel: URL ändern
history.pushState({}, '', '/neue-url');
pushState
: Fügt einen neuen Eintrag in den Verlauf (History) ein. Der Benutzer kann mit den Zurück-/Vorwärts-Buttons navigieren.replaceState
: Ersetzt den aktuellen Verlaufseintrag. Die Zurück-Navigation ist nicht möglich.
Verwendung in Svelte
Du kannst dies in einem Skript in einer Svelte-Komponente tun:
<script>
function changeUrl() {
history.pushState({}, '', '/neue-url');
}
</script>
<button on:click={changeUrl}>URL ändern</button>
2. URL ändern und Seite neu laden
Wenn du die URL ändern und die Seite komplett neu laden möchtest, kannst du die window.location
-Eigenschaft verwenden.
Beispiel: URL setzen und neu laden
window.location.href = '/neue-url';
Verwendung in Svelte
<script>
function reloadAndChangeUrl() {
window.location.href = '/neue-url';
}
</script>
<button on:click={reloadAndChangeUrl}>URL ändern und Seite neu laden</button>
3. Mit dem URL-Store (aus deinem Beispiel)
Wenn du einen URL-Store wie den in deinem Beispiel verwendest, kannst du die URL reaktiv ändern, indem du history.pushState
in Kombination mit dem Store nutzt.
Beispiel: URL-Wechsel mit einem Store
Hier ist eine angepasste Funktion für den Wechsel der URL:
function setUrl(newUrl) {
history.pushState({}, '', newUrl);
}
Verwendung in Svelte:
<script>
import urlStore from './path/to/store';
function changeToNewUrl() {
history.pushState({}, '', '/new-page');
// Der Store wird automatisch aktualisiert, weil er auf pushState lauscht
}
</script>
<button on:click={changeToNewUrl}>Zur neuen Seite wechseln</button>
4. URL mit Query-Parametern ändern
Wenn du nur die Abfrageparameter (?param=value
) ändern möchtest, kannst du URLSearchParams
verwenden:
Beispiel: Query-Parameter hinzufügen oder ändern
const params = new URLSearchParams(window.location.search);
params.set('name', 'Max');
history.pushState({}, '', `${window.location.pathname}?${params}`);
Verwendung in Svelte:
<script>
function addQueryParam() {
const params = new URLSearchParams(window.location.search);
params.set('lang', 'de');
history.pushState({}, '', `${window.location.pathname}?${params}`);
}
</script>
<button on:click={addQueryParam}>Sprache auf Deutsch setzen</button>
5. Hash-Änderungen
Für Änderungen des Hash-Anteils (#
) der URL kannst du einfach window.location.hash
verwenden:
Beispiel: Hash setzen
window.location.hash = 'section1';
Verwendung in Svelte:
<script>
function setHash() {
window.location.hash = 'section2';
}
</script>
<button on:click={setHash}>Zum Abschnitt 2 springen</button>
Zusammenfassung der Methoden
Methode
Beschreibung
Seiten-Neuladen
history.pushState
Ändert die URL, fügt neuen Verlaufseintrag hinzu
Nein
history.replaceState
Ändert die URL, ersetzt aktuellen Verlaufseintrag
Nein
window.location.href
Ändert die URL und lädt die Seite neu
Ja
window.location.hash
Ändert nur den Hash-Anteil der URL
Nein
URLSearchParams
+ pushState
Modifiziert die Query-Parameter der URL
Nein
Für Single-Page Applications (SPA) wird meistens history.pushState
bevorzugt, um eine reaktive Benutzererfahrung ohne Neuladen zu ermöglichen.