← Public packages
@kentcdodds/package-app-kit
Design tokens, PWA install/update, About/version, cache helpers, and optional realtime notes sync for Kody package apps.
starter-remix/app/assets/entry.ts
50 lines · 1.6 KB · TypeScriptimport { run } from 'remix/ui'
import { Counter } from '../ui/counter.tsx'
import { InstallCta } from '../ui/install-cta.tsx'
import { UpdateBanner } from '../ui/update-banner.tsx'
import { DoubleCheckButton } from '../ui/double-check-button.tsx'
import { AboutPanel } from '../ui/about-panel.tsx'
import { NotesDemo } from '../ui/notes-demo.tsx'
// One browser module — hydration resolves islands by export name (no import map).
const clientEntries: Record<string, unknown> = {
Counter,
InstallCta,
UpdateBanner,
DoubleCheckButton,
AboutPanel,
NotesDemo,
}
const app = run({
async loadModule(_moduleUrl, exportName) {
const component = clientEntries[exportName]
if (typeof component !== 'function') {
throw new Error(`Unknown client entry "${exportName}"`)
}
return component
},
})
app.addEventListener('error', (event) => {
console.error('Hydration error:', event.error)
})
function registerServiceWorker() {
if (!('serviceWorker' in navigator)) return
const root = document.documentElement
const appBase = (root.getAttribute('data-app-base') || '').replace(/\/$/, '')
const assetBase = (root.getAttribute('data-asset-base') || '').replace(/\/$/, '')
const swUrl =
root.getAttribute('data-sw-url') ||
(assetBase ? `${assetBase}/sw.js` : `${appBase}/sw.js`)
if (!appBase || !swUrl) return
void navigator.serviceWorker
.register(swUrl, { scope: `${appBase}/`, updateViaCache: 'none' })
.catch((error) => console.warn('SW register failed', error))
}
void app.ready().then(() => {
document.documentElement.dataset.hydrated = 'true'
registerServiceWorker()
})