Skip to content
← Public packages

@kentcdodds/package-app-kit

Design tokens, PWA install/update, About/version, cache helpers, and optional realtime notes sync for Kody package apps.

FollowFork

starter-tanstack/app/routes.ts

39 lines · 1.6 KB · TypeScript
/**
 * 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 || '/'
}