← Public packages
@kentcdodds/package-app-kit
Design tokens, PWA install/update, About/version, cache helpers, and optional realtime notes sync for Kody package apps.
/**
* Mount-aware path helpers (pure). Pass `appBasePath` from packageContext (Worker)
* or `document.documentElement.dataset.appBase` (browser) — never import kody:runtime here.
*/
export type AppRoutes = ReturnType<typeof createRoutes>
export function createRoutes(appBasePath = '') {
const base = String(appBasePath ?? '').replace(/\/+$/, '')
const href = (path: string) => {
if (!path || path === '/') return base || '/'
const normalized = path.startsWith('/') ? path : `/${path}`
return `${base}${normalized}`
}
return {
home: { path: '/', href: () => href('/') },
about: { path: '/about', href: () => href('/about') },
notes: {
path: '/notes',
index: { href: () => href('/notes') },
action: { href: () => href('/notes') },
},
manifest: { path: '/manifest.webmanifest', href: () => href('/manifest.webmanifest') },
icon192: { path: '/icons/icon-192.png', href: () => href('/icons/icon-192.png') },
icon512: { path: '/icons/icon-512.png', href: () => href('/icons/icon-512.png') },
versionApi: { path: '/api/version', href: () => href('/api/version') },
health: { path: '/health', href: () => href('/health') },
}
}
/** Relative path under the mount (leading slash, no trailing slash except root). */
export function relativePath(pathname: string, appBasePath: string): string {
const base = String(appBasePath ?? '').replace(/\/+$/, '')
let path = pathname || '/'
if (base && (path === base || path.startsWith(base + '/'))) {
path = path.slice(base.length) || '/'
}
if (path.length > 1 && path.endsWith('/')) path = path.slice(0, -1)
return path || '/'
}