@jasonshimmy/vite-plugin-cer-app 0.23.2 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/checks/lighthouse.d.ts +26 -0
- package/dist/cli/checks/lighthouse.d.ts.map +1 -0
- package/dist/cli/checks/lighthouse.js +121 -0
- package/dist/cli/checks/lighthouse.js.map +1 -0
- package/dist/cli/checks/links.d.ts +12 -0
- package/dist/cli/checks/links.d.ts.map +1 -0
- package/dist/cli/checks/links.js +89 -0
- package/dist/cli/checks/links.js.map +1 -0
- package/dist/cli/checks/performance.d.ts +17 -0
- package/dist/cli/checks/performance.d.ts.map +1 -0
- package/dist/cli/checks/performance.js +61 -0
- package/dist/cli/checks/performance.js.map +1 -0
- package/dist/cli/commands/check.d.ts +3 -0
- package/dist/cli/commands/check.d.ts.map +1 -0
- package/dist/cli/commands/check.js +85 -0
- package/dist/cli/commands/check.js.map +1 -0
- package/dist/cli/create/index.d.ts +11 -1
- package/dist/cli/create/index.d.ts.map +1 -1
- package/dist/cli/create/index.js +135 -65
- package/dist/cli/create/index.js.map +1 -1
- package/dist/cli/create/templates/spa/package.json.tpl +5 -3
- package/dist/cli/create/templates/ssg/cer.config.ts.tpl +2 -0
- package/dist/cli/create/templates/ssg/package.json.tpl +5 -3
- package/dist/cli/create/templates/ssr/package.json.tpl +5 -3
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/plugin/build-ssg.d.ts +22 -6
- package/dist/plugin/build-ssg.d.ts.map +1 -1
- package/dist/plugin/build-ssg.js +227 -17
- package/dist/plugin/build-ssg.js.map +1 -1
- package/dist/plugin/content/parser.d.ts.map +1 -1
- package/dist/plugin/content/parser.js +54 -10
- package/dist/plugin/content/parser.js.map +1 -1
- package/dist/plugin/dev-server.d.ts +4 -1
- package/dist/plugin/dev-server.d.ts.map +1 -1
- package/dist/plugin/dev-server.js.map +1 -1
- package/dist/plugin/dts-generator.d.ts.map +1 -1
- package/dist/plugin/dts-generator.js +50 -8
- package/dist/plugin/dts-generator.js.map +1 -1
- package/dist/plugin/generated-dir.d.ts +2 -0
- package/dist/plugin/generated-dir.d.ts.map +1 -1
- package/dist/plugin/generated-dir.js +17 -6
- package/dist/plugin/generated-dir.js.map +1 -1
- package/dist/plugin/html-post-process.d.ts +6 -0
- package/dist/plugin/html-post-process.d.ts.map +1 -1
- package/dist/plugin/html-post-process.js +24 -0
- package/dist/plugin/html-post-process.js.map +1 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +60 -13
- package/dist/plugin/index.js.map +1 -1
- package/dist/plugin/transforms/auto-import.d.ts.map +1 -1
- package/dist/plugin/transforms/auto-import.js +7 -0
- package/dist/plugin/transforms/auto-import.js.map +1 -1
- package/dist/plugin/transforms/prune-runtime-css.d.ts +8 -0
- package/dist/plugin/transforms/prune-runtime-css.d.ts.map +1 -0
- package/dist/plugin/transforms/prune-runtime-css.js +40 -0
- package/dist/plugin/transforms/prune-runtime-css.js.map +1 -0
- package/dist/runtime/app-template.d.ts +1 -1
- package/dist/runtime/app-template.d.ts.map +1 -1
- package/dist/runtime/app-template.js +206 -36
- package/dist/runtime/app-template.js.map +1 -1
- package/dist/runtime/composables/index.d.ts +4 -0
- package/dist/runtime/composables/index.d.ts.map +1 -1
- package/dist/runtime/composables/index.js +2 -0
- package/dist/runtime/composables/index.js.map +1 -1
- package/dist/runtime/composables/use-active-headings.d.ts +24 -0
- package/dist/runtime/composables/use-active-headings.d.ts.map +1 -0
- package/dist/runtime/composables/use-active-headings.js +112 -0
- package/dist/runtime/composables/use-active-headings.js.map +1 -0
- package/dist/runtime/composables/use-content-page.d.ts +45 -0
- package/dist/runtime/composables/use-content-page.d.ts.map +1 -0
- package/dist/runtime/composables/use-content-page.js +179 -0
- package/dist/runtime/composables/use-content-page.js.map +1 -0
- package/dist/runtime/composables/use-content-search.d.ts.map +1 -1
- package/dist/runtime/composables/use-content-search.js +1 -5
- package/dist/runtime/composables/use-content-search.js.map +1 -1
- package/dist/runtime/composables/use-fetch.d.ts +2 -1
- package/dist/runtime/composables/use-fetch.d.ts.map +1 -1
- package/dist/runtime/composables/use-fetch.js +112 -43
- package/dist/runtime/composables/use-fetch.js.map +1 -1
- package/dist/runtime/composables/use-route.d.ts.map +1 -1
- package/dist/runtime/composables/use-route.js +39 -11
- package/dist/runtime/composables/use-route.js.map +1 -1
- package/dist/runtime/content/client.js +2 -2
- package/dist/runtime/content/client.js.map +1 -1
- package/dist/runtime/entry-server-template.d.ts +16 -1
- package/dist/runtime/entry-server-template.d.ts.map +1 -1
- package/dist/runtime/entry-server-template.js +120 -13
- package/dist/runtime/entry-server-template.js.map +1 -1
- package/dist/types/config.d.ts +45 -4
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js.map +1 -1
- package/dist/types/middleware.d.ts +2 -2
- package/dist/types/middleware.d.ts.map +1 -1
- package/package.json +22 -19
- package/.github/copilot-instructions.md +0 -169
- package/.github/workflows/publish.yml +0 -257
- package/.nvmrc +0 -1
- package/CHANGELOG.md +0 -236
- package/CLAUDE.md +0 -113
- package/commits.txt +0 -1
- package/cypress.config.ts +0 -16
- package/docs/authentication.md +0 -285
- package/docs/cli.md +0 -324
- package/docs/components.md +0 -237
- package/docs/composables.md +0 -907
- package/docs/configuration.md +0 -696
- package/docs/content.md +0 -570
- package/docs/data-loading.md +0 -336
- package/docs/getting-started.md +0 -237
- package/docs/head-management.md +0 -212
- package/docs/i18n.md +0 -159
- package/docs/layouts.md +0 -224
- package/docs/middleware.md +0 -234
- package/docs/plugins.md +0 -170
- package/docs/rendering-modes.md +0 -377
- package/docs/routing.md +0 -485
- package/docs/server-api.md +0 -253
- package/docs/testing.md +0 -455
- package/docs/use-fetch.md +0 -183
- package/e2e/cypress/e2e/api.cy.ts +0 -123
- package/e2e/cypress/e2e/async-component.cy.ts +0 -27
- package/e2e/cypress/e2e/component-splitting.cy.ts +0 -50
- package/e2e/cypress/e2e/content.cy.ts +0 -425
- package/e2e/cypress/e2e/cookie.cy.ts +0 -85
- package/e2e/cypress/e2e/data.cy.ts +0 -158
- package/e2e/cypress/e2e/error-boundary.cy.ts +0 -88
- package/e2e/cypress/e2e/fouc.cy.ts +0 -254
- package/e2e/cypress/e2e/group-meta.cy.ts +0 -36
- package/e2e/cypress/e2e/head.cy.ts +0 -89
- package/e2e/cypress/e2e/i18n.cy.ts +0 -79
- package/e2e/cypress/e2e/interactive.cy.ts +0 -137
- package/e2e/cypress/e2e/isr-nested-runtime.cy.ts +0 -102
- package/e2e/cypress/e2e/jit-css-custom-colors.cy.ts +0 -43
- package/e2e/cypress/e2e/middleware-chain.cy.ts +0 -89
- package/e2e/cypress/e2e/middleware-status.cy.ts +0 -30
- package/e2e/cypress/e2e/middleware.cy.ts +0 -45
- package/e2e/cypress/e2e/navigate.cy.ts +0 -39
- package/e2e/cypress/e2e/observability.cy.ts +0 -77
- package/e2e/cypress/e2e/per-route-error.cy.ts +0 -42
- package/e2e/cypress/e2e/per-route-render.cy.ts +0 -70
- package/e2e/cypress/e2e/preview-hardening.cy.ts +0 -88
- package/e2e/cypress/e2e/routes.cy.ts +0 -128
- package/e2e/cypress/e2e/seo-meta.cy.ts +0 -108
- package/e2e/cypress/e2e/server-middleware.cy.ts +0 -46
- package/e2e/cypress/e2e/session-rotation.cy.ts +0 -25
- package/e2e/cypress/e2e/session.cy.ts +0 -73
- package/e2e/cypress/e2e/ssr-render-error.cy.ts +0 -68
- package/e2e/cypress/e2e/synthetic-404.cy.ts +0 -45
- package/e2e/cypress/e2e/use-page-data.cy.ts +0 -122
- package/e2e/cypress/e2e/use-state.cy.ts +0 -138
- package/e2e/cypress/support/commands.ts +0 -120
- package/e2e/cypress/support/e2e.ts +0 -10
- package/e2e/cypress/tsconfig.json +0 -14
- package/e2e/kitchen-sink/app/components/ks-badge.ts +0 -8
- package/e2e/kitchen-sink/app/composables/useKsCounter.ts +0 -9
- package/e2e/kitchen-sink/app/error.ts +0 -18
- package/e2e/kitchen-sink/app/layouts/admin.ts +0 -13
- package/e2e/kitchen-sink/app/layouts/default.ts +0 -25
- package/e2e/kitchen-sink/app/layouts/group.ts +0 -9
- package/e2e/kitchen-sink/app/layouts/minimal.ts +0 -7
- package/e2e/kitchen-sink/app/loading.ts +0 -9
- package/e2e/kitchen-sink/app/middleware/auth.ts +0 -9
- package/e2e/kitchen-sink/app/middleware/custom-log.ts +0 -4
- package/e2e/kitchen-sink/app/middleware/group-auth.ts +0 -7
- package/e2e/kitchen-sink/app/middleware/logger.ts +0 -14
- package/e2e/kitchen-sink/app/pages/(auth)/login.ts +0 -13
- package/e2e/kitchen-sink/app/pages/(auth)/protected.ts +0 -16
- package/e2e/kitchen-sink/app/pages/404.ts +0 -9
- package/e2e/kitchen-sink/app/pages/about.ts +0 -17
- package/e2e/kitchen-sink/app/pages/admin/_layout.ts +0 -1
- package/e2e/kitchen-sink/app/pages/admin/dashboard.ts +0 -11
- package/e2e/kitchen-sink/app/pages/async-component-error-test.ts +0 -18
- package/e2e/kitchen-sink/app/pages/async-component-test.ts +0 -18
- package/e2e/kitchen-sink/app/pages/blog/[slug].ts +0 -59
- package/e2e/kitchen-sink/app/pages/blog/index.ts +0 -51
- package/e2e/kitchen-sink/app/pages/content-blog.ts +0 -37
- package/e2e/kitchen-sink/app/pages/content-doc.ts +0 -42
- package/e2e/kitchen-sink/app/pages/content-fallback.ts +0 -36
- package/e2e/kitchen-sink/app/pages/content-guides.ts +0 -35
- package/e2e/kitchen-sink/app/pages/content-index.ts +0 -39
- package/e2e/kitchen-sink/app/pages/content-search.ts +0 -36
- package/e2e/kitchen-sink/app/pages/cookie-test.ts +0 -22
- package/e2e/kitchen-sink/app/pages/counter.ts +0 -17
- package/e2e/kitchen-sink/app/pages/group-auth-blocked.ts +0 -9
- package/e2e/kitchen-sink/app/pages/group-meta-test/_layout.ts +0 -6
- package/e2e/kitchen-sink/app/pages/group-meta-test/custom-mw.ts +0 -14
- package/e2e/kitchen-sink/app/pages/group-meta-test/page.ts +0 -9
- package/e2e/kitchen-sink/app/pages/group-meta-test/protected.ts +0 -8
- package/e2e/kitchen-sink/app/pages/head.ts +0 -20
- package/e2e/kitchen-sink/app/pages/i18n-test.ts +0 -14
- package/e2e/kitchen-sink/app/pages/index.ts +0 -27
- package/e2e/kitchen-sink/app/pages/isr-test.ts +0 -17
- package/e2e/kitchen-sink/app/pages/items/[id].ts +0 -20
- package/e2e/kitchen-sink/app/pages/jit-css-custom-colors-test.ts +0 -14
- package/e2e/kitchen-sink/app/pages/loader-error-test.ts +0 -13
- package/e2e/kitchen-sink/app/pages/loader-props-test.ts +0 -19
- package/e2e/kitchen-sink/app/pages/loader-response-error-test.ts +0 -13
- package/e2e/kitchen-sink/app/pages/middleware-chain-test.ts +0 -12
- package/e2e/kitchen-sink/app/pages/middleware-status-test.ts +0 -9
- package/e2e/kitchen-sink/app/pages/navigate-test.ts +0 -16
- package/e2e/kitchen-sink/app/pages/observability-test.ts +0 -25
- package/e2e/kitchen-sink/app/pages/per-route-error-test.error.ts +0 -13
- package/e2e/kitchen-sink/app/pages/per-route-error-test.ts +0 -15
- package/e2e/kitchen-sink/app/pages/plugin-dsd-test.ts +0 -10
- package/e2e/kitchen-sink/app/pages/render-error-test.ts +0 -12
- package/e2e/kitchen-sink/app/pages/render-server-test.ts +0 -12
- package/e2e/kitchen-sink/app/pages/render-spa-test.ts +0 -12
- package/e2e/kitchen-sink/app/pages/route-info.ts +0 -14
- package/e2e/kitchen-sink/app/pages/seo-test.ts +0 -23
- package/e2e/kitchen-sink/app/pages/session-rotation-test.ts +0 -25
- package/e2e/kitchen-sink/app/pages/use-state-test.ts +0 -37
- package/e2e/kitchen-sink/app/plugins/01.setup.ts +0 -7
- package/e2e/kitchen-sink/app/plugins/02.ks-plugin-components.ts +0 -27
- package/e2e/kitchen-sink/cer-auto-imports.d.ts +0 -51
- package/e2e/kitchen-sink/cer-env.d.ts +0 -35
- package/e2e/kitchen-sink/cer-tsconfig.json +0 -30
- package/e2e/kitchen-sink/cer.config.ts +0 -43
- package/e2e/kitchen-sink/content/01.guides/01.index.md +0 -8
- package/e2e/kitchen-sink/content/01.guides/02.intro.md +0 -8
- package/e2e/kitchen-sink/content/01.guides/10.advanced.md +0 -8
- package/e2e/kitchen-sink/content/blog/2026-04-01-hello.md +0 -26
- package/e2e/kitchen-sink/content/blog/2026-04-02-draft.md +0 -10
- package/e2e/kitchen-sink/content/blog/index.md +0 -8
- package/e2e/kitchen-sink/content/blog/no-frontmatter.md +0 -7
- package/e2e/kitchen-sink/content/docs/getting-started.md +0 -48
- package/e2e/kitchen-sink/content/index.md +0 -16
- package/e2e/kitchen-sink/server/api/echo.ts +0 -12
- package/e2e/kitchen-sink/server/api/health.ts +0 -3
- package/e2e/kitchen-sink/server/api/posts/[slug].ts +0 -11
- package/e2e/kitchen-sink/server/api/posts/index.ts +0 -5
- package/e2e/kitchen-sink/server/api/session.ts +0 -23
- package/e2e/kitchen-sink/server/data/posts.ts +0 -21
- package/e2e/kitchen-sink/server/middleware/01-headers.ts +0 -6
- package/e2e/kitchen-sink/server/middleware/02-status-test.ts +0 -10
- package/e2e/kitchen-sink/tsconfig.json +0 -3
- package/e2e/scripts/clean.mjs +0 -14
- package/eslint.config.ts +0 -22
- package/src/__tests__/cli/adapters/cloudflare-worker.integration.test.ts +0 -132
- package/src/__tests__/cli/adapters/cloudflare.test.ts +0 -332
- package/src/__tests__/cli/adapters/netlify-bridge.integration.test.ts +0 -139
- package/src/__tests__/cli/adapters/netlify.test.ts +0 -286
- package/src/__tests__/cli/adapters/vercel-launcher.integration.test.ts +0 -129
- package/src/__tests__/cli/adapters/vercel.test.ts +0 -263
- package/src/__tests__/cli/preview-hardening.test.ts +0 -265
- package/src/__tests__/cli/preview-isr.test.ts +0 -320
- package/src/__tests__/index.test.ts +0 -21
- package/src/__tests__/plugin/app-template.test.ts +0 -166
- package/src/__tests__/plugin/build-ssg-render.test.ts +0 -155
- package/src/__tests__/plugin/build-ssg.test.ts +0 -598
- package/src/__tests__/plugin/build-ssr.test.ts +0 -192
- package/src/__tests__/plugin/cer-app-plugin.test.ts +0 -552
- package/src/__tests__/plugin/content/emitter.test.ts +0 -117
- package/src/__tests__/plugin/content/loader.test.ts +0 -154
- package/src/__tests__/plugin/content/parser.test.ts +0 -381
- package/src/__tests__/plugin/content/path-utils.test.ts +0 -69
- package/src/__tests__/plugin/content/search.test.ts +0 -119
- package/src/__tests__/plugin/dev-server.test.ts +0 -813
- package/src/__tests__/plugin/dts-generator.test.ts +0 -394
- package/src/__tests__/plugin/entry-server-template.test.ts +0 -385
- package/src/__tests__/plugin/generated-dir.test.ts +0 -144
- package/src/__tests__/plugin/html-post-process.test.ts +0 -146
- package/src/__tests__/plugin/path-utils.test.ts +0 -411
- package/src/__tests__/plugin/resolve-config.test.ts +0 -233
- package/src/__tests__/plugin/scanner.test.ts +0 -186
- package/src/__tests__/plugin/transforms/auto-import.test.ts +0 -510
- package/src/__tests__/plugin/transforms/head-inject.test.ts +0 -178
- package/src/__tests__/plugin/virtual/composables.test.ts +0 -57
- package/src/__tests__/plugin/virtual/content-components.test.ts +0 -66
- package/src/__tests__/plugin/virtual/error.test.ts +0 -71
- package/src/__tests__/plugin/virtual/layouts.test.ts +0 -70
- package/src/__tests__/plugin/virtual/loading.test.ts +0 -72
- package/src/__tests__/plugin/virtual/middleware.test.ts +0 -83
- package/src/__tests__/plugin/virtual/plugins.test.ts +0 -129
- package/src/__tests__/plugin/virtual/routes.test.ts +0 -884
- package/src/__tests__/plugin/virtual/server-api.test.ts +0 -164
- package/src/__tests__/plugin/virtual/server-middleware.test.ts +0 -102
- package/src/__tests__/runtime/app-template.test.ts +0 -208
- package/src/__tests__/runtime/define-middleware.test.ts +0 -64
- package/src/__tests__/runtime/define-server-middleware.test.ts +0 -54
- package/src/__tests__/runtime/entry-client-template.test.ts +0 -61
- package/src/__tests__/runtime/isr-handler.test.ts +0 -338
- package/src/__tests__/runtime/oauth/handler.test.ts +0 -358
- package/src/__tests__/runtime/oauth/providers.test.ts +0 -47
- package/src/__tests__/runtime/oauth-index.test.ts +0 -43
- package/src/__tests__/runtime/use-auth.test.ts +0 -169
- package/src/__tests__/runtime/use-content-search-composable.test.ts +0 -405
- package/src/__tests__/runtime/use-content-search.test.ts +0 -163
- package/src/__tests__/runtime/use-content.test.ts +0 -226
- package/src/__tests__/runtime/use-cookie.test.ts +0 -277
- package/src/__tests__/runtime/use-fetch-component.test.ts +0 -214
- package/src/__tests__/runtime/use-fetch.test.ts +0 -377
- package/src/__tests__/runtime/use-head.test.ts +0 -311
- package/src/__tests__/runtime/use-inject-client.test.ts +0 -67
- package/src/__tests__/runtime/use-inject.test.ts +0 -66
- package/src/__tests__/runtime/use-locale.test.ts +0 -152
- package/src/__tests__/runtime/use-navigate.test.ts +0 -121
- package/src/__tests__/runtime/use-page-data.test.ts +0 -298
- package/src/__tests__/runtime/use-route.test.ts +0 -156
- package/src/__tests__/runtime/use-runtime-config.test.ts +0 -182
- package/src/__tests__/runtime/use-seo-meta.test.ts +0 -109
- package/src/__tests__/runtime/use-session.test.ts +0 -320
- package/src/__tests__/runtime/use-state.test.ts +0 -340
- package/src/__tests__/types/config.test.ts +0 -18
- package/src/cli/adapters/cloudflare.ts +0 -335
- package/src/cli/adapters/netlify.ts +0 -326
- package/src/cli/adapters/vercel.ts +0 -311
- package/src/cli/commands/adapt.ts +0 -84
- package/src/cli/commands/build.ts +0 -165
- package/src/cli/commands/dev.ts +0 -125
- package/src/cli/commands/generate.ts +0 -91
- package/src/cli/commands/preview-isr.ts +0 -172
- package/src/cli/commands/preview.ts +0 -523
- package/src/cli/create/index.ts +0 -275
- package/src/cli/create/templates/shared/.gitignore.tpl +0 -25
- package/src/cli/create/templates/shared/app/layouts/default.ts.tpl +0 -15
- package/src/cli/create/templates/shared/app/pages/index.ts.tpl +0 -8
- package/src/cli/create/templates/shared/index.html.tpl +0 -12
- package/src/cli/create/templates/shared/tsconfig.json.tpl +0 -6
- package/src/cli/create/templates/spa/cer.config.ts.tpl +0 -6
- package/src/cli/create/templates/spa/package.json.tpl +0 -18
- package/src/cli/create/templates/ssg/cer.config.ts.tpl +0 -10
- package/src/cli/create/templates/ssg/package.json.tpl +0 -19
- package/src/cli/create/templates/ssr/cer.config.ts.tpl +0 -6
- package/src/cli/create/templates/ssr/package.json.tpl +0 -18
- package/src/cli/index.ts +0 -22
- package/src/index.ts +0 -20
- package/src/plugin/build-ssg.ts +0 -403
- package/src/plugin/build-ssr.ts +0 -134
- package/src/plugin/content/emitter.ts +0 -50
- package/src/plugin/content/index.ts +0 -233
- package/src/plugin/content/parser.ts +0 -259
- package/src/plugin/content/path-utils.ts +0 -55
- package/src/plugin/content/scanner.ts +0 -26
- package/src/plugin/content/search.ts +0 -28
- package/src/plugin/dev-server.ts +0 -379
- package/src/plugin/dts-generator.ts +0 -273
- package/src/plugin/generated-dir.ts +0 -121
- package/src/plugin/html-post-process.ts +0 -96
- package/src/plugin/index.ts +0 -584
- package/src/plugin/path-utils.ts +0 -186
- package/src/plugin/scanner.ts +0 -65
- package/src/plugin/transforms/auto-import.ts +0 -206
- package/src/plugin/transforms/head-inject.ts +0 -161
- package/src/plugin/virtual/composables.ts +0 -28
- package/src/plugin/virtual/content-components.ts +0 -83
- package/src/plugin/virtual/error.ts +0 -34
- package/src/plugin/virtual/layouts.ts +0 -41
- package/src/plugin/virtual/loading.ts +0 -32
- package/src/plugin/virtual/middleware.ts +0 -45
- package/src/plugin/virtual/plugins.ts +0 -46
- package/src/plugin/virtual/routes.ts +0 -514
- package/src/plugin/virtual/server-api.ts +0 -85
- package/src/plugin/virtual/server-middleware.ts +0 -44
- package/src/runtime/app-template.ts +0 -377
- package/src/runtime/composables/define-middleware.ts +0 -17
- package/src/runtime/composables/define-server-middleware.ts +0 -18
- package/src/runtime/composables/index.ts +0 -27
- package/src/runtime/composables/use-auth.ts +0 -125
- package/src/runtime/composables/use-content-search.ts +0 -205
- package/src/runtime/composables/use-content.ts +0 -146
- package/src/runtime/composables/use-cookie.ts +0 -135
- package/src/runtime/composables/use-fetch.ts +0 -438
- package/src/runtime/composables/use-head.ts +0 -234
- package/src/runtime/composables/use-inject.ts +0 -49
- package/src/runtime/composables/use-locale.ts +0 -109
- package/src/runtime/composables/use-navigate.ts +0 -58
- package/src/runtime/composables/use-page-data.ts +0 -93
- package/src/runtime/composables/use-route.ts +0 -71
- package/src/runtime/composables/use-runtime-config.ts +0 -123
- package/src/runtime/composables/use-seo-meta.ts +0 -80
- package/src/runtime/composables/use-session.ts +0 -186
- package/src/runtime/composables/use-state.ts +0 -92
- package/src/runtime/content/client.ts +0 -168
- package/src/runtime/entry-client-template.ts +0 -39
- package/src/runtime/entry-server-template.ts +0 -493
- package/src/runtime/isr-handler.ts +0 -184
- package/src/runtime/oauth/handler.ts +0 -407
- package/src/runtime/oauth/index.ts +0 -49
- package/src/runtime/oauth/providers.ts +0 -38
- package/src/types/api.ts +0 -40
- package/src/types/config.ts +0 -379
- package/src/types/content.ts +0 -66
- package/src/types/index.ts +0 -7
- package/src/types/middleware.ts +0 -63
- package/src/types/page.ts +0 -117
- package/src/types/plugin.ts +0 -34
- package/tsconfig.build.json +0 -10
- package/tsconfig.json +0 -19
- package/vitest.config.ts +0 -33
package/docs/routing.md
DELETED
|
@@ -1,485 +0,0 @@
|
|
|
1
|
-
# Routing
|
|
2
|
-
|
|
3
|
-
Routes are automatically derived from files in the `app/pages/` directory. No manual route registration is required.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## File → route mapping
|
|
8
|
-
|
|
9
|
-
| File | Route path | Component tag |
|
|
10
|
-
|---|---|---|
|
|
11
|
-
| `app/pages/index.ts` | `/` | `page-index` |
|
|
12
|
-
| `app/pages/about.ts` | `/about` | `page-about` |
|
|
13
|
-
| `app/pages/blog/index.ts` | `/blog` | `page-blog` |
|
|
14
|
-
| `app/pages/blog/[slug].ts` | `/blog/:slug` | `page-blog-slug` |
|
|
15
|
-
| `app/pages/users/[id]/edit.ts` | `/users/:id/edit` | `page-users-id-edit` |
|
|
16
|
-
| `app/pages/404.ts` | `/:all*` (catch-all) | `page-404` |
|
|
17
|
-
| `app/pages/[...all].ts` | `/:all*` (catch-all) | `page-all` |
|
|
18
|
-
| `app/pages/(auth)/login.ts` | `/login` | `page-login` |
|
|
19
|
-
|
|
20
|
-
### Rules
|
|
21
|
-
|
|
22
|
-
1. **`index.ts`** — The `index` segment is stripped: `blog/index.ts` → `/blog`
|
|
23
|
-
2. **`[param]`** — Dynamic segment: `[slug].ts` → `:slug`
|
|
24
|
-
3. **`[...rest]`** — Catch-all segment: `[...all].ts` → `/:all*`
|
|
25
|
-
4. **`404.ts`** — Special shorthand: treated as a catch-all (`/:all*`) — the conventional 404 page
|
|
26
|
-
5. **`(group)/`** — Route group: directory name stripped from path, not from tag name
|
|
27
|
-
|
|
28
|
-
---
|
|
29
|
-
|
|
30
|
-
## Defining a page
|
|
31
|
-
|
|
32
|
-
Every file in `app/pages/` must call `component()` to register a custom element. The tag name is derived from the file path.
|
|
33
|
-
|
|
34
|
-
```ts
|
|
35
|
-
// app/pages/index.ts
|
|
36
|
-
component('page-index', () => {
|
|
37
|
-
return html`<h1>Home</h1>`
|
|
38
|
-
})
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
Because `autoImports.runtime` is `true` by default, `component` and `html` are injected automatically — no import statement is needed.
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
## Dynamic segments
|
|
46
|
-
|
|
47
|
-
Use square brackets in the filename to create a dynamic segment:
|
|
48
|
-
|
|
49
|
-
```ts
|
|
50
|
-
// app/pages/blog/[slug].ts
|
|
51
|
-
component('page-blog-slug', () => {
|
|
52
|
-
const props = useProps({ slug: '' })
|
|
53
|
-
|
|
54
|
-
return html`<h1>${props.slug}</h1>`
|
|
55
|
-
})
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
The `:slug` param is populated by the router and passed as a prop to the component.
|
|
59
|
-
|
|
60
|
-
---
|
|
61
|
-
|
|
62
|
-
## Catch-all routes and 404 pages
|
|
63
|
-
|
|
64
|
-
`404.ts` and `[...all].ts` both map to the same route pattern (`/:all*`), but they are not the same thing semantically:
|
|
65
|
-
|
|
66
|
-
- `404.ts` is the conventional not-found route. It should render your 404 UI, and the framework treats it as a real HTTP 404 route.
|
|
67
|
-
- `[...all].ts` is a general catch-all route. It can be used for not-found pages, but it is also the right choice for content-driven routing where valid URLs are resolved at runtime.
|
|
68
|
-
|
|
69
|
-
Use `404.ts` when the route is truly your global not-found page. Use `[...all].ts` when the route needs application logic to decide whether the current URL is valid.
|
|
70
|
-
|
|
71
|
-
**Option A — `404.ts` (recommended for true not-found pages)**
|
|
72
|
-
|
|
73
|
-
```ts
|
|
74
|
-
// app/pages/404.ts
|
|
75
|
-
component('page-404', () => {
|
|
76
|
-
return html`
|
|
77
|
-
<div>
|
|
78
|
-
<h1>404 — Page not found</h1>
|
|
79
|
-
<p><a href="/">← Back home</a></p>
|
|
80
|
-
</div>
|
|
81
|
-
`
|
|
82
|
-
})
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
The framework special-cases `404.ts` and automatically registers it as the catch-all route (`/:all*`). In SSR/SSG, it is treated as a real not-found route and returns HTTP 404.
|
|
86
|
-
|
|
87
|
-
**Option B — `[...name].ts` explicit catch-all**
|
|
88
|
-
|
|
89
|
-
```ts
|
|
90
|
-
// app/pages/[...all].ts
|
|
91
|
-
component('page-all', () => {
|
|
92
|
-
return html`<h1>404 — Page not found</h1>`
|
|
93
|
-
})
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
This still produces the same route pattern (`/:all*`), but unlike `404.ts` it is not assumed to be a 404 by default. If the page successfully resolves data for the current URL, the response stays HTTP 200. If the page decides the URL is missing, throw or return a 404 from your loader explicitly.
|
|
97
|
-
|
|
98
|
-
This is the pattern to use for content-driven sites, documentation trees, storefront catalogs, and other apps where one catch-all page resolves many valid nested URLs.
|
|
99
|
-
|
|
100
|
-
**Synthetic 404 fallback (automatic)**
|
|
101
|
-
|
|
102
|
-
If your app defines **no** catch-all route at all (neither `404.ts` nor `[...all].ts`), the framework injects a synthetic `/:all*` route that returns HTTP 404 without crashing. This protects production SSR apps from returning 500 for unknown paths during the period before you add a real 404 page.
|
|
103
|
-
|
|
104
|
-
The synthetic route:
|
|
105
|
-
- Returns `HTTP 404` in SSR mode
|
|
106
|
-
- Renders the global error component (`app/error.ts`) if one is defined, passing `error="Not Found"` and `status="404"` as attributes
|
|
107
|
-
- Renders an empty `<div>` if no error component is defined
|
|
108
|
-
|
|
109
|
-
Add a real `404.ts` to customize the experience; the synthetic fallback is removed automatically once one exists.
|
|
110
|
-
|
|
111
|
-
Note that `app/error.ts` is a global error boundary, not a route page. You can also define per-route error boundaries with `foo.error.ts` or directory-level `_error.ts`. See [data-loading.md](./data-loading.md#error-boundary--apperrorts) for the global error page and the route-level error-boundary section later in this guide for per-route overrides.
|
|
112
|
-
|
|
113
|
-
---
|
|
114
|
-
|
|
115
|
-
## Route groups
|
|
116
|
-
|
|
117
|
-
Wrap a directory name in parentheses to create a route group. The directory is excluded from the URL path but the files inside are still scanned:
|
|
118
|
-
|
|
119
|
-
```
|
|
120
|
-
app/pages/
|
|
121
|
-
(auth)/
|
|
122
|
-
login.ts → /login
|
|
123
|
-
register.ts → /register
|
|
124
|
-
dashboard.ts → /dashboard
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
Route groups are useful for collocating related pages without affecting their URLs.
|
|
128
|
-
|
|
129
|
-
### Nested route groups
|
|
130
|
-
|
|
131
|
-
Multiple route-group segments can be nested. All parenthesised segments are stripped when computing the URL path:
|
|
132
|
-
|
|
133
|
-
```
|
|
134
|
-
app/pages/
|
|
135
|
-
(auth)/
|
|
136
|
-
(admin)/
|
|
137
|
-
settings.ts → /settings
|
|
138
|
-
(marketing)/
|
|
139
|
-
about.ts → /about
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
The component tag name is also derived from the full file path — group segments are stripped from the tag name as well:
|
|
143
|
-
|
|
144
|
-
| File | Route path | Component tag |
|
|
145
|
-
|---|---|---|
|
|
146
|
-
| `(auth)/login.ts` | `/login` | `page-login` |
|
|
147
|
-
| `(auth)/(admin)/settings.ts` | `/settings` | `page-settings` |
|
|
148
|
-
|
|
149
|
-
---
|
|
150
|
-
|
|
151
|
-
## i18n routing
|
|
152
|
-
|
|
153
|
-
When `i18n` is configured in `cer.config.ts`, the build system automatically generates locale-prefixed route variants for every page. You do not need to duplicate your page files.
|
|
154
|
-
|
|
155
|
-
```ts
|
|
156
|
-
// cer.config.ts
|
|
157
|
-
export default defineConfig({
|
|
158
|
-
i18n: {
|
|
159
|
-
locales: ['en', 'fr', 'de'],
|
|
160
|
-
defaultLocale: 'en',
|
|
161
|
-
strategy: 'prefix_except_default',
|
|
162
|
-
},
|
|
163
|
-
})
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
With the above config, `app/pages/about.ts` produces:
|
|
167
|
-
|
|
168
|
-
| Path | Locale |
|
|
169
|
-
|---|---|
|
|
170
|
-
| `/about` | `en` (default) |
|
|
171
|
-
| `/fr/about` | `fr` |
|
|
172
|
-
| `/de/about` | `de` |
|
|
173
|
-
|
|
174
|
-
Both routes load the same page component — only the detected locale differs.
|
|
175
|
-
|
|
176
|
-
Use `useLocale()` inside your pages and components to read the current locale and generate locale-aware links. `useLocale()` is auto-imported — no import statement is needed.
|
|
177
|
-
|
|
178
|
-
See [i18n.md](./i18n.md) for full configuration options, strategies, `switchLocalePath`, SSR/SSG behavior, and a locale switcher example.
|
|
179
|
-
|
|
180
|
-
---
|
|
181
|
-
|
|
182
|
-
## Page metadata (`meta` export)
|
|
183
|
-
|
|
184
|
-
Export a `meta` object from any page file to customize behavior:
|
|
185
|
-
|
|
186
|
-
```ts
|
|
187
|
-
// app/pages/blog/[slug].ts
|
|
188
|
-
import type { PageMeta } from '@jasonshimmy/vite-plugin-cer-app/types'
|
|
189
|
-
|
|
190
|
-
component('page-blog-slug', () => { /* ... */ })
|
|
191
|
-
|
|
192
|
-
export const meta: PageMeta = {
|
|
193
|
-
// Which layout wraps this page (defaults to 'default' if app/layouts/default.ts exists)
|
|
194
|
-
layout: 'default',
|
|
195
|
-
|
|
196
|
-
// Named middleware to run before this page loads
|
|
197
|
-
middleware: ['auth'],
|
|
198
|
-
|
|
199
|
-
// Per-page hydration strategy
|
|
200
|
-
hydrate: 'load', // 'load' | 'idle' | 'visible' | 'none'
|
|
201
|
-
|
|
202
|
-
// SSG: enumerate paths for dynamic routes
|
|
203
|
-
ssg: {
|
|
204
|
-
paths: async () => [
|
|
205
|
-
{ params: { slug: 'hello-world' } },
|
|
206
|
-
{ params: { slug: 'second-post' } },
|
|
207
|
-
],
|
|
208
|
-
},
|
|
209
|
-
}
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
### `meta.layout`
|
|
213
|
-
|
|
214
|
-
Which layout to wrap this page in. The value must match a filename (without extension) in `app/layouts/`. Set to `false` or `''` (empty string) to render the page without any layout, or omit to use the default layout.
|
|
215
|
-
|
|
216
|
-
### `meta.middleware`
|
|
217
|
-
|
|
218
|
-
Array of named middleware to run before navigating to this page. Names must match files in `app/middleware/` (without extension).
|
|
219
|
-
|
|
220
|
-
### `meta.hydrate`
|
|
221
|
-
|
|
222
|
-
Controls when the page component activates (hydrates) on the client after SSR. The server always renders full HTML regardless of this setting — it only affects client-side JS activation timing.
|
|
223
|
-
|
|
224
|
-
| Value | Behavior | Browser API |
|
|
225
|
-
|---|---|---|
|
|
226
|
-
| `'load'` | Hydrates immediately on page load (default) | — |
|
|
227
|
-
| `'idle'` | Defers until the browser has finished higher-priority work | `requestIdleCallback` (falls back to `setTimeout` in Safari) |
|
|
228
|
-
| `'visible'` | Defers until `<cer-layout-view>` enters the viewport (falls back to observing `document.body` if `<cer-layout-view>` is not found) | `IntersectionObserver` |
|
|
229
|
-
| `'none'` | Never hydrates — SSR HTML stays as-is, no JS activation | — |
|
|
230
|
-
|
|
231
|
-
```ts
|
|
232
|
-
// app/pages/marketing.ts — defer activation until idle
|
|
233
|
-
export const meta = {
|
|
234
|
-
hydrate: 'idle',
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// app/pages/legal/terms.ts — fully static, no JS needed
|
|
238
|
-
export const meta = {
|
|
239
|
-
hydrate: 'none',
|
|
240
|
-
}
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
**`'none'` and `usePageData`:** When `hydrate: 'none'` is set, the page component never activates and `usePageData()` loader data is not consumed. Avoid using `loader` on pages with `hydrate: 'none'` — the serialized `window.__CER_DATA__` will be present in the HTML but never read or cleaned up by the client.
|
|
244
|
-
|
|
245
|
-
**SPA mode:** `meta.hydrate` has no effect in SPA mode — there is no SSR output to preserve, so the component always activates immediately.
|
|
246
|
-
|
|
247
|
-
### `meta.ssg.paths`
|
|
248
|
-
|
|
249
|
-
Required for dynamic routes in SSG mode. Returns an array of `{ params }` objects, one per URL to generate:
|
|
250
|
-
|
|
251
|
-
```ts
|
|
252
|
-
export const meta = {
|
|
253
|
-
ssg: {
|
|
254
|
-
paths: async () => {
|
|
255
|
-
const posts = await fetch('/api/posts').then(r => r.json())
|
|
256
|
-
return posts.map((post) => ({ params: { slug: post.slug } }))
|
|
257
|
-
},
|
|
258
|
-
},
|
|
259
|
-
}
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
Catch-all pages can use `meta.ssg.paths` too:
|
|
263
|
-
|
|
264
|
-
```ts
|
|
265
|
-
// app/pages/[...all].ts
|
|
266
|
-
export const meta = {
|
|
267
|
-
ssg: {
|
|
268
|
-
paths: async () => [
|
|
269
|
-
{ params: { all: 'docs/getting-started' } },
|
|
270
|
-
{ params: { all: 'docs/routing' } },
|
|
271
|
-
],
|
|
272
|
-
},
|
|
273
|
-
}
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
For content-backed catch-all pages that resolve URLs with `queryContent()`, SSG can also auto-discover concrete paths from the content store when `ssg.routes` is set to `'auto'`.
|
|
277
|
-
|
|
278
|
-
### `meta.ssg.revalidate`
|
|
279
|
-
|
|
280
|
-
**Type:** `number` (seconds)
|
|
281
|
-
|
|
282
|
-
Enables Incremental Static Regeneration (ISR) for the route. When set, the preview server caches the rendered HTML and serves it until the TTL expires. After expiry, stale HTML is served immediately while a fresh render runs in the background (stale-while-revalidate).
|
|
283
|
-
|
|
284
|
-
```ts
|
|
285
|
-
// app/pages/blog/[slug].ts
|
|
286
|
-
export const meta = {
|
|
287
|
-
ssg: {
|
|
288
|
-
revalidate: 60, // re-render at most once per minute
|
|
289
|
-
paths: async () => { /* ... */ },
|
|
290
|
-
},
|
|
291
|
-
}
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
See [Rendering Modes — ISR](rendering-modes.md#isr--incremental-static-regeneration) for full details.
|
|
295
|
-
|
|
296
|
-
### `meta.transition`
|
|
297
|
-
|
|
298
|
-
**Type:** `string | boolean`
|
|
299
|
-
|
|
300
|
-
Attaches transition metadata to the route. The value is extracted at build time and emitted as `meta.transition` on the route object — the framework does **not** apply any CSS or DOM changes automatically.
|
|
301
|
-
|
|
302
|
-
```ts
|
|
303
|
-
// app/pages/about.ts
|
|
304
|
-
export const meta = {
|
|
305
|
-
transition: 'fade', // stored as route.meta.transition at runtime
|
|
306
|
-
}
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
Read the value in your navigation handler or layout to implement transitions yourself:
|
|
310
|
-
|
|
311
|
-
```ts
|
|
312
|
-
import routes from 'virtual:cer-routes'
|
|
313
|
-
const about = routes.find(r => r.path === '/about')
|
|
314
|
-
// about.meta.transition → 'fade'
|
|
315
|
-
```
|
|
316
|
-
|
|
317
|
-
Example — apply a CSS class during navigation using a plugin:
|
|
318
|
-
|
|
319
|
-
```ts
|
|
320
|
-
// app/plugins/transitions.ts
|
|
321
|
-
export default {
|
|
322
|
-
setup({ router }) {
|
|
323
|
-
router.subscribe((to) => {
|
|
324
|
-
const name = to.meta?.transition
|
|
325
|
-
if (name) document.documentElement.setAttribute('data-transition', String(name))
|
|
326
|
-
else document.documentElement.removeAttribute('data-transition')
|
|
327
|
-
})
|
|
328
|
-
},
|
|
329
|
-
}
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
```css
|
|
333
|
-
[data-transition="fade"] cer-layout-view {
|
|
334
|
-
animation: fadeIn 0.2s ease;
|
|
335
|
-
}
|
|
336
|
-
@keyframes fadeIn {
|
|
337
|
-
from { opacity: 0 }
|
|
338
|
-
to { opacity: 1 }
|
|
339
|
-
}
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
Set to `false` to explicitly mark a page as having no transition (useful when a catch-all or default would otherwise apply one).
|
|
343
|
-
|
|
344
|
-
### `meta.render`
|
|
345
|
-
|
|
346
|
-
**Type:** `'static' | 'server' | 'spa'`
|
|
347
|
-
|
|
348
|
-
Overrides the global rendering mode for a single route. Useful in mixed apps where most pages share one strategy but a few need different treatment.
|
|
349
|
-
|
|
350
|
-
| Value | Behavior |
|
|
351
|
-
|---|---|
|
|
352
|
-
| `'server'` | Always renders server-side. In SSG mode the route is **skipped** during the static build — it is never pre-rendered. |
|
|
353
|
-
| `'static'` | Always serves pre-rendered HTML from disk. In the SSR **preview server**, the framework looks for `dist/<path>/index.html`; falls back to SSR if the file is not found. In SSG mode the route is still pre-rendered at build time as normal. |
|
|
354
|
-
| `'spa'` | Client-only. In SSR mode the server returns the SPA shell (`index.html`) without rendering. In SSG mode the route is skipped. |
|
|
355
|
-
|
|
356
|
-
```ts
|
|
357
|
-
// app/pages/dashboard.ts — always SSR even in an otherwise SSG app
|
|
358
|
-
export const meta = {
|
|
359
|
-
render: 'server',
|
|
360
|
-
}
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
```ts
|
|
364
|
-
// app/pages/profile.ts — client-only (auth wall, no crawlable content)
|
|
365
|
-
export const meta = {
|
|
366
|
-
render: 'spa',
|
|
367
|
-
}
|
|
368
|
-
```
|
|
369
|
-
|
|
370
|
-
```ts
|
|
371
|
-
// app/pages/legal/privacy.ts — force static even in SSR mode
|
|
372
|
-
export const meta = {
|
|
373
|
-
render: 'static',
|
|
374
|
-
}
|
|
375
|
-
```
|
|
376
|
-
|
|
377
|
-
---
|
|
378
|
-
|
|
379
|
-
### Per-route error components
|
|
380
|
-
|
|
381
|
-
You can co-locate an error component alongside any page file. When the page's `loader` throws, the framework renders the error component instead of the global `app/error.ts` fallback.
|
|
382
|
-
|
|
383
|
-
**Two file conventions are supported:**
|
|
384
|
-
|
|
385
|
-
| File | Scope |
|
|
386
|
-
|---|---|
|
|
387
|
-
| `app/pages/foo.error.ts` | Error boundary for `app/pages/foo.ts` only |
|
|
388
|
-
| `app/pages/blog/_error.ts` | Error boundary for every page under `app/pages/blog/` |
|
|
389
|
-
|
|
390
|
-
Both files are **excluded from the route list** — they are never reachable as standalone routes.
|
|
391
|
-
|
|
392
|
-
```ts
|
|
393
|
-
// app/pages/blog/[slug].error.ts
|
|
394
|
-
component('page-blog-slug-error', () => {
|
|
395
|
-
const props = useProps({ error: '', status: '' })
|
|
396
|
-
|
|
397
|
-
return html`
|
|
398
|
-
<div>
|
|
399
|
-
<h1>Post unavailable (${props.status})</h1>
|
|
400
|
-
<p>${props.error}</p>
|
|
401
|
-
<a href="/blog">← Back to blog</a>
|
|
402
|
-
</div>
|
|
403
|
-
`
|
|
404
|
-
})
|
|
405
|
-
```
|
|
406
|
-
|
|
407
|
-
The error component receives `error` (the thrown error message) and `status` (the HTTP status code, e.g. `"422"` or `"500"`) as string attributes.
|
|
408
|
-
|
|
409
|
-
**Resolution order:** page-level (`foo.error.ts`) > directory-level (`_error.ts`) > global (`app/error.ts`).
|
|
410
|
-
|
|
411
|
-
---
|
|
412
|
-
|
|
413
|
-
## Route sorting
|
|
414
|
-
|
|
415
|
-
When multiple routes are matched, the router resolves them in this priority order:
|
|
416
|
-
|
|
417
|
-
1. **Static routes** — exact path matches (e.g. `/about`)
|
|
418
|
-
2. **Dynamic routes** — paths with parameters (e.g. `/blog/:slug`)
|
|
419
|
-
3. **Catch-all routes** — `/*` last
|
|
420
|
-
|
|
421
|
-
Within each tier, routes are sorted alphabetically.
|
|
422
|
-
|
|
423
|
-
---
|
|
424
|
-
|
|
425
|
-
## Navigation with `<router-link>`
|
|
426
|
-
|
|
427
|
-
`initRouter()` registers a `<router-link>` built-in custom element that renders a client-side navigation link. Use it anywhere in your pages or layouts instead of a plain `<a>` tag when you want the router to handle the navigation (no full page reload):
|
|
428
|
-
|
|
429
|
-
```ts
|
|
430
|
-
// app/layouts/default.ts
|
|
431
|
-
component('layout-default', () => {
|
|
432
|
-
return html`
|
|
433
|
-
<nav>
|
|
434
|
-
<router-link to="/">Home</router-link>
|
|
435
|
-
<router-link to="/about">About</router-link>
|
|
436
|
-
<router-link to="/blog">Blog</router-link>
|
|
437
|
-
</nav>
|
|
438
|
-
<main><slot></slot></main>
|
|
439
|
-
`
|
|
440
|
-
})
|
|
441
|
-
```
|
|
442
|
-
|
|
443
|
-
`<router-link to="/path">` calls `router.push(path)` on click, which triggers the wrapped navigation handler (loading state, error capture, etc.). Use a plain `<a href="/path">` when you need a standard browser navigation or an external link.
|
|
444
|
-
|
|
445
|
-
---
|
|
446
|
-
|
|
447
|
-
## Loading state — `app/loading.ts`
|
|
448
|
-
|
|
449
|
-
Create `app/loading.ts` to display a loading indicator while a route chunk is being fetched during client-side navigation. The file must export a custom element named `page-loading`:
|
|
450
|
-
|
|
451
|
-
```ts
|
|
452
|
-
// app/loading.ts
|
|
453
|
-
component('page-loading', () => {
|
|
454
|
-
return html`
|
|
455
|
-
<div style="display:flex;align-items:center;gap:8px;padding:1rem">
|
|
456
|
-
<span style="width:14px;height:14px;border:2px solid #ccc;border-top-color:#555;border-radius:50%;animation:spin 0.7s linear infinite;display:inline-block"></span>
|
|
457
|
-
Loading…
|
|
458
|
-
<style>@keyframes spin { to { transform: rotate(360deg) } }</style>
|
|
459
|
-
</div>
|
|
460
|
-
`
|
|
461
|
-
})
|
|
462
|
-
```
|
|
463
|
-
|
|
464
|
-
**Behaviour:**
|
|
465
|
-
|
|
466
|
-
- `page-loading` is rendered in place of the normal layout + page tree while the route chunk is being loaded.
|
|
467
|
-
- Once the chunk resolves and the page is ready to render, `page-loading` is replaced automatically.
|
|
468
|
-
- `page-loading` is never included in SSR or SSG output — it only appears during client-side navigation.
|
|
469
|
-
|
|
470
|
-
If `app/loading.ts` does not exist, navigation proceeds without any intermediate state (the previous page stays visible until the new one is ready).
|
|
471
|
-
|
|
472
|
-
---
|
|
473
|
-
|
|
474
|
-
## Virtual module
|
|
475
|
-
|
|
476
|
-
The route list is exposed as the virtual module `virtual:cer-routes`, which you can import in any plugin or composable:
|
|
477
|
-
|
|
478
|
-
```ts
|
|
479
|
-
import routes from 'virtual:cer-routes'
|
|
480
|
-
|
|
481
|
-
// routes is an array of:
|
|
482
|
-
// { path: string, component: string, load: () => Promise<module> }
|
|
483
|
-
```
|
|
484
|
-
|
|
485
|
-
The `load` function is a dynamic import back to the original page file, enabling code splitting per route.
|