Skip to content

Commit d2e9cd7

Browse files
committed
Fix asset and route paths for subdirectory deployment
1 parent 0fc5387 commit d2e9cd7

11 files changed

Lines changed: 53 additions & 41 deletions

File tree

src/lib/components/layout/Header.svelte

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<script lang="ts">
2+
import { base } from '$app/paths';
23
import { page } from '$app/stores';
34
import Icon from '$lib/components/common/Icon.svelte';
45
import { tooltip } from '$lib/components/common/Tooltip.svelte';
@@ -16,7 +17,7 @@
1617
let activePackage = $derived.by(() => {
1718
const path = $page.url.pathname;
1819
for (const id of packageOrder) {
19-
if (path.startsWith(`/${id}`)) {
20+
if (path.startsWith(`${base}/${id}`)) {
2021
return id;
2122
}
2223
}
@@ -32,14 +33,14 @@
3233
<Icon name="menu" size={14} />
3334
</button>
3435
{/if}
35-
<a href="/" class="icon-btn" use:tooltip={'Docs Home'}>
36-
<img src="/favicon.png" alt="PathSim" class="logo-icon" />
36+
<a href="{base}/" class="icon-btn" use:tooltip={'Docs Home'}>
37+
<img src="{base}/favicon.png" alt="PathSim" class="logo-icon" />
3738
</a>
3839
<nav class="package-tabs">
3940
{#each packageOrder as id}
4041
{@const pkg = packages[id]}
4142
<a
42-
href={pkg.docs}
43+
href="{base}/{pkg.docs}"
4344
class="package-tab"
4445
class:active={activePackage === id}
4546
use:tooltip={pkg.name}

src/lib/components/layout/MobileDrawer.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<script lang="ts">
2+
import { base } from '$app/paths';
23
import Icon from '$lib/components/common/Icon.svelte';
34
import Sidebar from './Sidebar.svelte';
45
import { packages, packageOrder, type PackageId } from '$lib/config/packages';
@@ -48,7 +49,7 @@
4849
{#each packageOrder as id}
4950
{@const pkg = packages[id]}
5051
<a
51-
href={pkg.docs}
52+
href="{base}/{pkg.docs}"
5253
class="mobile-package-link"
5354
class:active={packageId === id}
5455
onclick={onClose}

src/lib/components/layout/Sidebar.svelte

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<script lang="ts">
2+
import { base } from '$app/paths';
23
import { page } from '$app/stores';
34
import { goto } from '$app/navigation';
45
import Icon from '$lib/components/common/Icon.svelte';
@@ -26,7 +27,7 @@
2627
let isExamplesListPage = $derived($page.url.pathname.endsWith('/examples'));
2728
2829
function isActive(path: string): boolean {
29-
return $page.url.pathname === path;
30+
return $page.url.pathname === `${base}/${path}`;
3031
}
3132
3233
function handleSearchKeydown(event: KeyboardEvent) {
@@ -44,7 +45,7 @@
4445
type: result.type,
4546
parentClass: result.parentClass
4647
});
47-
goto(result.path);
48+
goto(`${base}/${result.path}`);
4849
}
4950
5051
function handleTocNavigate(id: string) {
@@ -99,7 +100,7 @@
99100
{:else}
100101
<nav class="sidebar-nav">
101102
{#each items as item}
102-
<a href={item.path} class="sidebar-item" class:active={isActive(item.path)}>
103+
<a href="{base}/{item.path}" class="sidebar-item" class:active={isActive(item.path)}>
103104
{#if item.icon}
104105
<Icon name={item.icon} size={14} />
105106
{/if}

src/lib/components/pages/PackageExamples.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script lang="ts">
22
import { onMount, onDestroy } from 'svelte';
3+
import { base } from '$app/paths';
34
import { goto } from '$app/navigation';
45
import Icon from '$lib/components/common/Icon.svelte';
56
import Tooltip from '$lib/components/common/Tooltip.svelte';
@@ -34,7 +35,7 @@
3435
3536
onMount(async () => {
3637
try {
37-
manifest = await loadManifest(packageId);
38+
manifest = await loadManifest(packageId, base);
3839
// Populate store for sidebar TOC with grouped data
3940
if (manifest) {
4041
const grouped = groupByCategory(manifest.notebooks, manifest.categories);

src/lib/components/pages/PackageOverview.svelte

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<script lang="ts">
2+
import { base } from '$app/paths';
23
import Icon from '$lib/components/common/Icon.svelte';
34
import Tooltip, { tooltip } from '$lib/components/common/Tooltip.svelte';
45
import NotebookCell from '$lib/components/common/NotebookCell.svelte';
@@ -34,15 +35,15 @@
3435
<Tooltip />
3536

3637
<div class="hero">
37-
<img src={pkg.logo} alt={pkg.name} class="hero-logo" />
38+
<img src="{base}/{pkg.logo}" alt={pkg.name} class="hero-logo" />
3839
<p class="description">{pkg.description}</p>
3940
<div class="hero-actions">
40-
<a href={pkg.api} class="action-card">
41+
<a href="{base}/{pkg.api}" class="action-card">
4142
<Icon name="braces" size={20} />
4243
<span class="action-label">API</span>
4344
</a>
4445
{#if pkg.examples}
45-
<a href={pkg.examples} class="action-card">
46+
<a href="{base}/{pkg.examples}" class="action-card">
4647
<Icon name="play" size={20} />
4748
<span class="action-label">Examples</span>
4849
</a>

src/lib/config/packages.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,10 @@ export const packages: Record<PackageId, PackageConfig> = {
6464
name: 'PathSim',
6565
shortName: 'pathsim',
6666
description: 'A Python library for building and simulating continuous-time, discrete-time, and hybrid dynamical systems using a block-diagram approach.',
67-
logo: '/pathsim_logo.png',
68-
docs: '/pathsim',
69-
api: '/pathsim/api',
70-
examples: '/pathsim/examples',
67+
logo: 'pathsim_logo.png',
68+
docs: 'pathsim',
69+
api: 'pathsim/api',
70+
examples: 'pathsim/examples',
7171
pypi: `${external.pypi}/pathsim`,
7272
github: `${external.github}/pathsim`,
7373
features: [
@@ -118,9 +118,9 @@ scope.plot()`,
118118
name: 'PathSim-Chem',
119119
shortName: 'chem',
120120
description: 'Chemical engineering blocks for PathSim, including reactors, heat exchangers, and separation units.',
121-
logo: '/pathsim_chem_logo.png',
122-
docs: '/chem',
123-
api: '/chem/api',
121+
logo: 'pathsim_chem_logo.png',
122+
docs: 'chem',
123+
api: 'chem/api',
124124
examples: null,
125125
pypi: `${external.pypi}/pathsim-chem`,
126126
github: `${external.github}/pathsim-chem`,
@@ -141,9 +141,9 @@ scope.plot()`,
141141
name: 'PathSim-Vehicle',
142142
shortName: 'vehicle',
143143
description: 'Vehicle dynamics blocks for PathSim, including tire models, suspension systems, and powertrain components.',
144-
logo: '/pathsim_vehicle_logo.png',
145-
docs: '/vehicle',
146-
api: '/vehicle/api',
144+
logo: 'pathsim_vehicle_logo.png',
145+
docs: 'vehicle',
146+
api: 'vehicle/api',
147147
examples: null,
148148
pypi: null,
149149
github: `${external.github}/pathsim-vehicle`,

src/lib/notebook/manifest.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ export interface NotebookManifest {
4141
/**
4242
* Load manifest for a package.
4343
*/
44-
export async function loadManifest(packageId: string): Promise<NotebookManifest> {
45-
const response = await fetch(`/notebooks/${packageId}/manifest.json`);
44+
export async function loadManifest(packageId: string, basePath: string = ''): Promise<NotebookManifest> {
45+
const response = await fetch(`${basePath}/notebooks/${packageId}/manifest.json`);
4646
if (!response.ok) {
4747
throw new Error(`Failed to load manifest for ${packageId}: ${response.status}`);
4848
}
@@ -52,8 +52,8 @@ export async function loadManifest(packageId: string): Promise<NotebookManifest>
5252
/**
5353
* Load a notebook JSON file.
5454
*/
55-
export async function loadNotebook(packageId: string, filename: string): Promise<unknown> {
56-
const response = await fetch(`/notebooks/${packageId}/${filename}`);
55+
export async function loadNotebook(packageId: string, filename: string, basePath: string = ''): Promise<unknown> {
56+
const response = await fetch(`${basePath}/notebooks/${packageId}/${filename}`);
5757
if (!response.ok) {
5858
throw new Error(`Failed to load notebook ${filename}: ${response.status}`);
5959
}

src/lib/utils/search.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ function buildSearchIndex(): SearchResult[] {
3333
const results: SearchResult[] = [];
3434

3535
for (const [packageId, pkg] of Object.entries(apiData)) {
36-
const basePath = `/${packageId}/api`;
36+
const basePath = `${packageId}/api`;
3737

3838
for (const [moduleName, module] of Object.entries(pkg.modules)) {
3939
// Add module
@@ -89,6 +89,9 @@ function buildSearchIndex(): SearchResult[] {
8989
return results;
9090
}
9191

92+
// Base path for fetching, set via initExamplesSearch
93+
let basePath = '';
94+
9295
/**
9396
* Load example manifests and build example search results
9497
*/
@@ -100,7 +103,7 @@ async function loadExampleManifests(): Promise<SearchResult[]> {
100103

101104
for (const packageId of packageIds) {
102105
try {
103-
const response = await fetch(`/notebooks/${packageId}/manifest.json`);
106+
const response = await fetch(`${basePath}/notebooks/${packageId}/manifest.json`);
104107
if (!response.ok) continue;
105108

106109
const manifest: NotebookManifest = await response.json();
@@ -110,7 +113,7 @@ async function loadExampleManifests(): Promise<SearchResult[]> {
110113
type: 'example',
111114
name: notebook.title,
112115
description: notebook.description || '',
113-
path: `/${packageId}/examples/${notebook.slug}`,
116+
path: `${packageId}/examples/${notebook.slug}`,
114117
packageId,
115118
moduleName: notebook.category,
116119
tags: notebook.tags
@@ -140,7 +143,8 @@ function getSearchIndex(): SearchResult[] {
140143
/**
141144
* Initialize examples in the search index (call once on app load)
142145
*/
143-
export async function initExamplesSearch(): Promise<void> {
146+
export async function initExamplesSearch(base: string = ''): Promise<void> {
147+
basePath = base;
144148
await loadExampleManifests();
145149
}
146150

src/routes/+layout.svelte

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<script lang="ts">
22
import '../app.css';
33
import { onMount } from 'svelte';
4+
import { base } from '$app/paths';
45
import { page } from '$app/stores';
56
import Tooltip from '$lib/components/common/Tooltip.svelte';
67
import Icon from '$lib/components/common/Icon.svelte';
@@ -17,7 +18,7 @@
1718
let currentPackage = $derived.by(() => {
1819
const path = $page.url.pathname;
1920
for (const id of packageOrder) {
20-
if (path.startsWith(`/${id}`)) {
21+
if (path.startsWith(`${base}/${id}`)) {
2122
return id;
2223
}
2324
}
@@ -34,7 +35,7 @@
3435
document.documentElement.setAttribute('data-theme', theme);
3536
3637
// Initialize examples in search index
37-
initExamplesSearch();
38+
initExamplesSearch(base);
3839
3940
const handleKeydown = (e: KeyboardEvent) => {
4041
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {

src/routes/+page.svelte

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<script lang="ts">
2+
import { base } from '$app/paths';
23
import { goto } from '$app/navigation';
34
import Icon from '$lib/components/common/Icon.svelte';
45
import Tooltip, { tooltip } from '$lib/components/common/Tooltip.svelte';
@@ -24,7 +25,7 @@
2425
type: result.type,
2526
parentClass: result.parentClass
2627
});
27-
goto(result.path);
28+
goto(`${base}/${result.path}`);
2829
}
2930
3031
function getTypeIcon(type: SearchResult['type']): string {
@@ -48,7 +49,7 @@
4849
<div class="page-wrapper">
4950
<main>
5051
<header class="hero">
51-
<img src="/pathsim_logo.png" alt="PathSim" class="hero-logo" />
52+
<img src="{base}/pathsim_logo.png" alt="PathSim" class="hero-logo" />
5253
<p class="tagline">Documentation for the PathSim ecosystem</p>
5354
<p class="description">
5455
API reference, tutorials, and examples for PathSim and its domain-specific toolboxes.
@@ -123,10 +124,10 @@
123124
<div class="panel-header">
124125
<span>{pkg.shortName}</span>
125126
<div class="header-actions">
126-
<a href={pkg.api} class="icon-btn" use:tooltip={'API'}>
127+
<a href="{base}/{pkg.api}" class="icon-btn" use:tooltip={'API'}>
127128
<Icon name="braces" size={14} />
128129
</a>
129-
<a href={pkg.docs} class="icon-btn" use:tooltip={'Docs'}>
130+
<a href="{base}/{pkg.docs}" class="icon-btn" use:tooltip={'Docs'}>
130131
<Icon name="book" size={14} />
131132
</a>
132133
{#if pkg.pypi}
@@ -135,7 +136,7 @@
135136
</a>
136137
{/if}
137138
{#if pkg.examples}
138-
<a href={pkg.examples} class="icon-btn" use:tooltip={'Examples'}>
139+
<a href="{base}/{pkg.examples}" class="icon-btn" use:tooltip={'Examples'}>
139140
<Icon name="play" size={14} />
140141
</a>
141142
{/if}
@@ -144,8 +145,8 @@
144145
</a>
145146
</div>
146147
</div>
147-
<a href={pkg.docs} class="package-body">
148-
<img src={pkg.logo} alt={pkg.name} />
148+
<a href="{base}/{pkg.docs}" class="package-body">
149+
<img src="{base}/{pkg.logo}" alt={pkg.name} />
149150
</a>
150151
</div>
151152
{/each}

0 commit comments

Comments
 (0)