refactor: migrate hrefs to resolve()/asset() from $app/paths
Replace string-literal and template-literal hrefs across the codebase with the modern SvelteKit 2.26+ resolve() and asset() APIs. Migration makes route IDs explicit, type-checked against generated $app/types, and base-path-aware. Two codemod scripts handle the bulk; remaining ambiguous, query-bearing, and precomputed-href cases are converted manually at the assignment sites.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { resolve } from '$app/paths';
|
||||
import Symbol from "./Symbol.svelte"
|
||||
import ThemeToggle from "./ThemeToggle.svelte"
|
||||
import type { Snippet } from 'svelte';
|
||||
@@ -329,7 +330,7 @@ nav {
|
||||
<div>
|
||||
|
||||
<nav class:no-links={!links}>
|
||||
<a href="/" aria-label="Home" class="home-link" class:full={fullSymbol}><Symbol /></a>
|
||||
<a href={resolve('/')} aria-label="Home" class="home-link" class:full={fullSymbol}><Symbol /></a>
|
||||
{#if links}
|
||||
<div class="links-wrapper">
|
||||
{@render links()}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { resolve } from '$app/paths';
|
||||
import { onMount } from "svelte";
|
||||
import { page } from '$app/stores';
|
||||
import LogIn from '@lucide/svelte/icons/log-in';
|
||||
@@ -153,10 +154,10 @@
|
||||
<p>({user.nickname})</p>
|
||||
<ul>
|
||||
{#if user.groups?.includes('rezepte_users')}
|
||||
<li><a href="/{recipeLang}/administration">Administration</a></li>
|
||||
<li><a href={resolve('/[recipeLang=recipeLang]/administration', { recipeLang })}>Administration</a></li>
|
||||
{/if}
|
||||
<li><a href="https://sso.bocken.org/if/user/#/settings" >Einstellungen</a></li>
|
||||
<li><a href="/logout?callbackUrl={encodeURIComponent(getLogoutCallbackUrl($page.url.pathname))}">Log Out</a></li>
|
||||
<li><a href={`${resolve('/logout')}?callbackUrl=${encodeURIComponent(getLogoutCallbackUrl($page.url.pathname))}`}>Log Out</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -164,7 +165,7 @@
|
||||
{:else}
|
||||
<a
|
||||
class="entry login-link"
|
||||
href="/login?callbackUrl={encodeURIComponent($page.url.pathname + $page.url.search)}"
|
||||
href={`${resolve('/login')}?callbackUrl=${encodeURIComponent($page.url.pathname + $page.url.search)}`}
|
||||
aria-label={lang === 'de' ? 'Anmelden' : 'Login'}
|
||||
title={lang === 'de' ? 'Anmelden' : 'Login'}
|
||||
>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<script>
|
||||
import { resolve } from '$app/paths';
|
||||
import { onMount } from 'svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/stores';
|
||||
@@ -243,7 +244,7 @@
|
||||
</div>
|
||||
|
||||
{#if payment}
|
||||
<EditButton href="/{root}/payments/edit/{paymentId}" />
|
||||
<EditButton href={resolve('/[cospendRoot=cospendRoot]/payments/edit/[id]', { cospendRoot: root, id: paymentId })} />
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { resolve } from '$app/paths';
|
||||
import Shield from '@lucide/svelte/icons/shield';
|
||||
import Flame from '@lucide/svelte/icons/flame';
|
||||
|
||||
@@ -18,7 +19,7 @@
|
||||
<a
|
||||
class="case-tab"
|
||||
class:active={active === 'contra'}
|
||||
href="/{faithLang}/{slug}/contra"
|
||||
href={resolve('/[faithLang=faithLang]/[apologetikSlug=apologetikSlug]/contra', { faithLang, apologetikSlug: slug })}
|
||||
>
|
||||
<Shield class="ct-glyph" size={14} strokeWidth={2} aria-hidden="true" />
|
||||
<span>{l.contra}</span>
|
||||
@@ -26,7 +27,7 @@
|
||||
<a
|
||||
class="case-tab"
|
||||
class:active={active === 'pro'}
|
||||
href="/{faithLang}/{slug}/pro"
|
||||
href={resolve('/[faithLang=faithLang]/[apologetikSlug=apologetikSlug]/pro', { faithLang, apologetikSlug: slug })}
|
||||
>
|
||||
<Flame class="ct-glyph" size={14} strokeWidth={2} aria-hidden="true" />
|
||||
<span>{l.pro}</span>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<script>
|
||||
import { resolve } from '$app/paths';
|
||||
import { page } from '$app/stores';
|
||||
import { getEnrichedExerciseById } from '$lib/data/exercisedb';
|
||||
import { detectFitnessLang, fitnessSlugs } from '$lib/js/fitnessI18n';
|
||||
@@ -14,7 +15,7 @@
|
||||
{#if plain}
|
||||
<span class="exercise-plain">{exercise.localName}</span>
|
||||
{:else}
|
||||
<a href="/fitness/{sl.exercises}/{exerciseId}" class="exercise-link">{exercise.localName}</a>
|
||||
<a href={resolve('/fitness/[exercises=fitnessExercises]/[id]', { exercises: sl.exercises, id: exerciseId })} class="exercise-link">{exercise.localName}</a>
|
||||
{/if}
|
||||
{:else}
|
||||
<span class="exercise-unknown">Unknown Exercise</span>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<script>
|
||||
import { resolve } from '$app/paths';
|
||||
import { page } from '$app/stores';
|
||||
import { browser } from '$app/environment';
|
||||
import { untrack } from 'svelte';
|
||||
@@ -477,7 +478,7 @@
|
||||
<span class="fs-result-cal">{item.calories}<small> kcal</small></span>
|
||||
</button>
|
||||
{#if showDetailLinks && (item.source === 'bls' || item.source === 'usda' || item.source === 'off')}
|
||||
<a class="fs-detail-link" href="/fitness/{s.nutrition}/food/{item.source}/{item.id}" aria-label="View details">
|
||||
<a class="fs-detail-link" href={resolve('/fitness/[nutrition=fitnessNutrition]/food/[source]/[id]', { nutrition: s.nutrition, source: item.source, id: item.id })} aria-label="View details">
|
||||
<ExternalLink size={13} />
|
||||
</a>
|
||||
{/if}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<script>
|
||||
import { resolve } from '$app/paths';
|
||||
import { page } from '$app/stores';
|
||||
import { getExerciseById, getExerciseMetrics } from '$lib/data/exercises';
|
||||
import Clock from '@lucide/svelte/icons/clock';
|
||||
@@ -152,7 +153,7 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
<a href="/fitness/{sl.history}/{session._id}" class="session-card">
|
||||
<a href={resolve('/fitness/[history=fitnessHistory]/[id]', { history: sl.history, id: session._id })} class="session-card">
|
||||
<div class="card-top">
|
||||
<h3 class="session-name">{session.name}</h3>
|
||||
<span class="session-date">{formatDate(session.startTime)} · {formatTime(session.startTime)}</span>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { resolve } from '$app/paths';
|
||||
import "$lib/css/shake.css"
|
||||
let { icon, ...restProps } = $props<{ icon: string, [key: string]: any }>();
|
||||
</script>
|
||||
@@ -26,4 +27,4 @@
|
||||
}
|
||||
|
||||
</style>
|
||||
<a href="/rezepte/icon/{icon}" {...restProps} >{icon}</a>
|
||||
<a href={resolve('/[recipeLang=recipeLang]/icon/[icon]', { recipeLang: 'rezepte', icon })} {...restProps} >{icon}</a>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { resolve } from '$app/paths';
|
||||
import type { TranslatedRecipeType } from '$types/types';
|
||||
import TranslationFieldComparison from './TranslationFieldComparison.svelte';
|
||||
import CreateIngredientList from '$lib/components/recipes/CreateIngredientList.svelte';
|
||||
@@ -758,7 +759,7 @@ button:disabled {
|
||||
{#each untranslatedBaseRecipes as baseRecipe}
|
||||
<li>
|
||||
<strong>{baseRecipe.name}</strong>
|
||||
<a href="/de/edit/{baseRecipe.shortName}" target="_blank" rel="noopener noreferrer">
|
||||
<a href={resolve('/[recipeLang=recipeLang]/edit/[name]', { recipeLang: 'de', name: baseRecipe.shortName })} target="_blank" rel="noopener noreferrer">
|
||||
Open in new tab →
|
||||
</a>
|
||||
</li>
|
||||
|
||||
Reference in New Issue
Block a user