@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/head-management.md
DELETED
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
# Head Management
|
|
2
|
-
|
|
3
|
-
The `useHead()` composable manages `<title>`, `<meta>`, `<link>`, `<script>`, and `<style>` tags in the document `<head>`.
|
|
4
|
-
|
|
5
|
-
- **In SSR/SSG mode** — tags are collected during rendering and injected into the HTML before it is sent to the browser.
|
|
6
|
-
- **In client mode (SPA or after hydration)** — tags are imperatively applied to `document.head`.
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## Import
|
|
11
|
-
|
|
12
|
-
`useHead` is auto-imported in files inside `app/pages/`, `app/layouts/`, `app/components/`, and root convention files (e.g. `app/loading.ts`). No import statement is needed in those locations.
|
|
13
|
-
|
|
14
|
-
If you use `useHead` outside those directories, import it explicitly:
|
|
15
|
-
|
|
16
|
-
```ts
|
|
17
|
-
import { useHead } from '@jasonshimmy/vite-plugin-cer-app/composables'
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
## Basic usage
|
|
23
|
-
|
|
24
|
-
```ts
|
|
25
|
-
component('page-about', () => {
|
|
26
|
-
useHead({
|
|
27
|
-
title: 'About Us',
|
|
28
|
-
meta: [
|
|
29
|
-
{ name: 'description', content: 'Learn more about our team.' },
|
|
30
|
-
{ property: 'og:title', content: 'About Us' },
|
|
31
|
-
{ property: 'og:type', content: 'website' },
|
|
32
|
-
],
|
|
33
|
-
link: [
|
|
34
|
-
{ rel: 'canonical', href: 'https://example.com/about' },
|
|
35
|
-
],
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
return html`<h1>About</h1>`
|
|
39
|
-
})
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
---
|
|
43
|
-
|
|
44
|
-
## `HeadInput` interface
|
|
45
|
-
|
|
46
|
-
```ts
|
|
47
|
-
interface HeadInput {
|
|
48
|
-
title?: string
|
|
49
|
-
meta?: Array<Record<string, string>>
|
|
50
|
-
link?: Array<Record<string, string>>
|
|
51
|
-
script?: Array<Record<string, string>>
|
|
52
|
-
style?: Array<Record<string, string>>
|
|
53
|
-
}
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
All fields are optional. Each array item is a map of HTML attribute names to values. Use `innerHTML` as a special key to set element inner content for `<script>` and `<style>`.
|
|
57
|
-
|
|
58
|
-
---
|
|
59
|
-
|
|
60
|
-
## Title
|
|
61
|
-
|
|
62
|
-
```ts
|
|
63
|
-
useHead({ title: 'My Page' })
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
- **SSR/SSG:** Rendered as `<title>My Page</title>` injected before `</head>`.
|
|
67
|
-
- **Client:** Sets `document.title = 'My Page'`.
|
|
68
|
-
- **Deduplication:** Last call wins — subsequent `useHead({ title })` calls overwrite the previous title.
|
|
69
|
-
|
|
70
|
-
HTML entities in the title are escaped automatically (`<`, `>`, `&`).
|
|
71
|
-
|
|
72
|
-
---
|
|
73
|
-
|
|
74
|
-
## Meta tags
|
|
75
|
-
|
|
76
|
-
```ts
|
|
77
|
-
useHead({
|
|
78
|
-
meta: [
|
|
79
|
-
{ name: 'description', content: 'Page description' },
|
|
80
|
-
{ property: 'og:title', content: 'OG Title' },
|
|
81
|
-
{ charset: 'UTF-8' },
|
|
82
|
-
{ name: 'robots', content: 'index, follow' },
|
|
83
|
-
],
|
|
84
|
-
})
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
### Deduplication
|
|
88
|
-
|
|
89
|
-
Meta tags are deduplicated by their key attribute:
|
|
90
|
-
|
|
91
|
-
| Attribute present | Dedup key |
|
|
92
|
-
|---|---|
|
|
93
|
-
| `name` | `name` value |
|
|
94
|
-
| `property` | `property` value |
|
|
95
|
-
| `charset` | `charset` value |
|
|
96
|
-
| None of the above | Full JSON serialization |
|
|
97
|
-
|
|
98
|
-
When the same key is set twice, the later value replaces the earlier one.
|
|
99
|
-
|
|
100
|
-
### Client mode
|
|
101
|
-
|
|
102
|
-
- If a `meta[name="…"]` or `meta[property="…"]` element already exists in the DOM, its attributes are updated in place.
|
|
103
|
-
- Otherwise a new `<meta>` element is created and appended to `<head>`.
|
|
104
|
-
- `charset` meta tags are **not** updated on the client (the `name`/`property` check requires one of those attributes).
|
|
105
|
-
|
|
106
|
-
---
|
|
107
|
-
|
|
108
|
-
## Link tags
|
|
109
|
-
|
|
110
|
-
```ts
|
|
111
|
-
useHead({
|
|
112
|
-
link: [
|
|
113
|
-
{ rel: 'canonical', href: 'https://example.com/about' },
|
|
114
|
-
{ rel: 'stylesheet', href: '/styles/extra.css' },
|
|
115
|
-
{ rel: 'preload', href: '/fonts/inter.woff2', as: 'font', type: 'font/woff2', crossorigin: '' },
|
|
116
|
-
],
|
|
117
|
-
})
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
### Deduplication
|
|
121
|
-
|
|
122
|
-
Deduplicated by `rel` + `href` key. Same `rel`/`href` pair appearing twice results in a single tag.
|
|
123
|
-
|
|
124
|
-
### Client mode
|
|
125
|
-
|
|
126
|
-
- If a `link[rel="…"][href="…"]` already exists, its attributes are updated in place.
|
|
127
|
-
- Otherwise a new `<link>` element is created.
|
|
128
|
-
|
|
129
|
-
---
|
|
130
|
-
|
|
131
|
-
## Script tags
|
|
132
|
-
|
|
133
|
-
```ts
|
|
134
|
-
useHead({
|
|
135
|
-
script: [
|
|
136
|
-
// External script by src
|
|
137
|
-
{ src: '/analytics.js', defer: '', type: 'text/javascript' },
|
|
138
|
-
|
|
139
|
-
// Inline script with innerHTML
|
|
140
|
-
{ innerHTML: 'window.__APP_VERSION__ = "1.0.0"' },
|
|
141
|
-
|
|
142
|
-
// JSON-LD structured data
|
|
143
|
-
{
|
|
144
|
-
type: 'application/ld+json',
|
|
145
|
-
innerHTML: JSON.stringify({
|
|
146
|
-
'@context': 'https://schema.org',
|
|
147
|
-
'@type': 'WebPage',
|
|
148
|
-
name: 'About Us',
|
|
149
|
-
}),
|
|
150
|
-
},
|
|
151
|
-
],
|
|
152
|
-
})
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
Script tags are **not** deduplicated — every call appends a new `<script>` to the output.
|
|
156
|
-
|
|
157
|
-
### Client mode (script deduplication)
|
|
158
|
-
|
|
159
|
-
On the client, scripts **with `src`** are deduplicated: a `<script src="…">` is only added if no `script[src="…"]` already exists in the DOM. Scripts without `src` (inline) are always appended.
|
|
160
|
-
|
|
161
|
-
---
|
|
162
|
-
|
|
163
|
-
## Style tags
|
|
164
|
-
|
|
165
|
-
```ts
|
|
166
|
-
useHead({
|
|
167
|
-
style: [
|
|
168
|
-
{ innerHTML: ':root { --color-primary: #007bff }' },
|
|
169
|
-
{ type: 'text/css', innerHTML: 'body { margin: 0 }' },
|
|
170
|
-
],
|
|
171
|
-
})
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
Style tags are not deduplicated.
|
|
175
|
-
|
|
176
|
-
> **Note:** `style` tag support via `useHead` is SSR/SSG only. Client-side `useHead({ style: [...] })` calls are no-ops — style tags are not injected into `document.head` on the client.
|
|
177
|
-
|
|
178
|
-
---
|
|
179
|
-
|
|
180
|
-
## SSR: collection and injection
|
|
181
|
-
|
|
182
|
-
During SSR rendering, `useHead()` calls are collected via a request-scoped array. After rendering is complete, the collected tags are serialized and injected before `</head>` in the HTML shell.
|
|
183
|
-
|
|
184
|
-
You can use the underlying primitives directly from `@jasonshimmy/vite-plugin-cer-app/composables` if you need manual control:
|
|
185
|
-
|
|
186
|
-
```ts
|
|
187
|
-
import { beginHeadCollection, endHeadCollection, serializeHeadTags } from '@jasonshimmy/vite-plugin-cer-app/composables'
|
|
188
|
-
|
|
189
|
-
// Before rendering:
|
|
190
|
-
beginHeadCollection()
|
|
191
|
-
|
|
192
|
-
// ... render component tree (useHead() calls accumulate) ...
|
|
193
|
-
|
|
194
|
-
// After rendering:
|
|
195
|
-
const collected = endHeadCollection()
|
|
196
|
-
const headHtml = serializeHeadTags(collected)
|
|
197
|
-
// Inject headHtml into your HTML template
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
---
|
|
201
|
-
|
|
202
|
-
## Merging rules summary
|
|
203
|
-
|
|
204
|
-
| Tag type | Deduplication key | Merge behavior |
|
|
205
|
-
|---|---|---|
|
|
206
|
-
| `<title>` | N/A | Last wins |
|
|
207
|
-
| `<meta name>` | `name` value | Later replaces earlier |
|
|
208
|
-
| `<meta property>` | `property` value | Later replaces earlier |
|
|
209
|
-
| `<meta charset>` | `charset` value | Later replaces earlier |
|
|
210
|
-
| `<link>` | `rel` + `href` | Later replaces earlier |
|
|
211
|
-
| `<script>` | None (SSR) / `src` (client) | Accumulated (external deduped on client) |
|
|
212
|
-
| `<style>` | None | Always accumulated |
|
package/docs/i18n.md
DELETED
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
# 🌍 Internationalisation (i18n)
|
|
2
|
-
|
|
3
|
-
`vite-plugin-cer-app` has built-in support for locale-aware URL routing and the `useLocale()` composable. No external package is required.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Configuration
|
|
8
|
-
|
|
9
|
-
Add an `i18n` block to `cer.config.ts`:
|
|
10
|
-
|
|
11
|
-
```ts
|
|
12
|
-
// cer.config.ts
|
|
13
|
-
import { defineConfig } from '@jasonshimmy/vite-plugin-cer-app'
|
|
14
|
-
|
|
15
|
-
export default defineConfig({
|
|
16
|
-
i18n: {
|
|
17
|
-
locales: ['en', 'fr', 'de'],
|
|
18
|
-
defaultLocale: 'en',
|
|
19
|
-
strategy: 'prefix_except_default', // default
|
|
20
|
-
},
|
|
21
|
-
})
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
### Options
|
|
25
|
-
|
|
26
|
-
| Option | Type | Default | Description |
|
|
27
|
-
|---|---|---|---|
|
|
28
|
-
| `locales` | `string[]` | — | All supported locale codes. |
|
|
29
|
-
| `defaultLocale` | `string` | — | The fallback locale. |
|
|
30
|
-
| `strategy` | `'prefix' \| 'prefix_except_default' \| 'no_prefix'` | `'prefix_except_default'` | How locales appear in URLs. |
|
|
31
|
-
|
|
32
|
-
### Strategies
|
|
33
|
-
|
|
34
|
-
| Strategy | Default locale URL | Other locale URL |
|
|
35
|
-
|---|---|---|
|
|
36
|
-
| `'prefix'` | `/en/about` | `/fr/about` |
|
|
37
|
-
| `'prefix_except_default'` | `/about` | `/fr/about` |
|
|
38
|
-
| `'no_prefix'` | `/about` | `/about` (locale from cookie/header only) |
|
|
39
|
-
|
|
40
|
-
> **Recommendation:** Use `'prefix_except_default'` for most projects. It keeps your existing English URLs intact while adding locale prefixes for other languages.
|
|
41
|
-
|
|
42
|
-
---
|
|
43
|
-
|
|
44
|
-
## How It Works
|
|
45
|
-
|
|
46
|
-
When `i18n` is configured, the build system automatically generates locale-prefixed route variants for every page. You do **not** need to duplicate your page files.
|
|
47
|
-
|
|
48
|
-
For example, with `locales: ['en', 'fr']` and `strategy: 'prefix_except_default'`, the page `app/pages/about.ts` generates:
|
|
49
|
-
|
|
50
|
-
| Path | Locale |
|
|
51
|
-
|---|---|
|
|
52
|
-
| `/about` | `en` (default) |
|
|
53
|
-
| `/fr/about` | `fr` |
|
|
54
|
-
|
|
55
|
-
Both routes load the same page component — only the detected locale differs.
|
|
56
|
-
|
|
57
|
-
---
|
|
58
|
-
|
|
59
|
-
## `useLocale()`
|
|
60
|
-
|
|
61
|
-
The `useLocale()` composable is **auto-imported** in all page, layout, and component files. It works isomorphically: on the server it reads the URL path via AsyncLocalStorage; on the client it reads `window.location.pathname`.
|
|
62
|
-
|
|
63
|
-
```ts
|
|
64
|
-
const {
|
|
65
|
-
locale, // 'fr' — current locale code
|
|
66
|
-
locales, // ['en', 'fr'] — all configured locales
|
|
67
|
-
defaultLocale, // 'en' — the default locale
|
|
68
|
-
switchLocalePath, // function — build a URL in another locale
|
|
69
|
-
} = useLocale()
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### `switchLocalePath(targetLocale, path?)`
|
|
73
|
-
|
|
74
|
-
Returns the equivalent path in the target locale. When `path` is omitted the current pathname is used.
|
|
75
|
-
|
|
76
|
-
```ts
|
|
77
|
-
// On /fr/about
|
|
78
|
-
switchLocalePath('en') // → '/about'
|
|
79
|
-
switchLocalePath('en', '/fr/about') // → '/about'
|
|
80
|
-
switchLocalePath('de', '/fr/about') // → '/de/about'
|
|
81
|
-
|
|
82
|
-
// On /about (default locale)
|
|
83
|
-
switchLocalePath('fr') // → '/fr/about'
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
### Example — locale switcher component
|
|
87
|
-
|
|
88
|
-
```ts
|
|
89
|
-
// app/components/locale-switcher.ts
|
|
90
|
-
component('locale-switcher', () => {
|
|
91
|
-
const { locale, locales, switchLocalePath } = useLocale()
|
|
92
|
-
|
|
93
|
-
return html`
|
|
94
|
-
<nav>
|
|
95
|
-
${locales.map((l) => html`
|
|
96
|
-
<a
|
|
97
|
-
href="${switchLocalePath(l)}"
|
|
98
|
-
aria-current="${l === locale ? 'true' : 'false'}"
|
|
99
|
-
>${l.toUpperCase()}</a>
|
|
100
|
-
`)}
|
|
101
|
-
</nav>
|
|
102
|
-
`
|
|
103
|
-
})
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
### Example — locale-aware page
|
|
107
|
-
|
|
108
|
-
```ts
|
|
109
|
-
// app/pages/about.ts
|
|
110
|
-
component('page-about', () => {
|
|
111
|
-
const { locale } = useLocale()
|
|
112
|
-
|
|
113
|
-
const headings = { en: 'About Us', fr: 'À propos', de: 'Über uns' }
|
|
114
|
-
|
|
115
|
-
return html`<h1>${headings[locale] ?? headings.en}</h1>`
|
|
116
|
-
})
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
---
|
|
120
|
-
|
|
121
|
-
## SSR / SSG
|
|
122
|
-
|
|
123
|
-
`useLocale()` works identically in SSR and SSG mode because it reads the request URL from AsyncLocalStorage on the server rather than from `window`.
|
|
124
|
-
|
|
125
|
-
For SSG, the build system pre-renders **each locale path** as a separate static HTML file:
|
|
126
|
-
|
|
127
|
-
```
|
|
128
|
-
dist/
|
|
129
|
-
index.html (en — default locale)
|
|
130
|
-
about/index.html (en — default locale)
|
|
131
|
-
fr/
|
|
132
|
-
index.html
|
|
133
|
-
about/index.html
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
---
|
|
137
|
-
|
|
138
|
-
## Detecting Locale Without URL Prefixes (`no_prefix`)
|
|
139
|
-
|
|
140
|
-
When `strategy: 'no_prefix'` is used, `useLocale()` always returns `defaultLocale` because there is no locale in the URL. To support multi-language content without URL changes you can:
|
|
141
|
-
|
|
142
|
-
1. Store the user's preferred locale in a cookie and read it in a server middleware.
|
|
143
|
-
2. Use the `Accept-Language` request header in a loader.
|
|
144
|
-
|
|
145
|
-
```ts
|
|
146
|
-
// app/pages/home.ts
|
|
147
|
-
export const loader = async ({ req }) => {
|
|
148
|
-
const lang = req.headers['accept-language']?.split(',')[0]?.split('-')[0] ?? 'en'
|
|
149
|
-
return { lang }
|
|
150
|
-
}
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
---
|
|
154
|
-
|
|
155
|
-
## Limitations
|
|
156
|
-
|
|
157
|
-
- Per-route middleware applies to **all** locale variants of a route.
|
|
158
|
-
- `no_prefix` strategy does not auto-detect locale from `Accept-Language` — you must do this manually in a loader or server middleware.
|
|
159
|
-
- Locale switching via `switchLocalePath` generates URLs but does **not** automatically navigate; pair it with `navigateTo()` for programmatic locale changes.
|
package/docs/layouts.md
DELETED
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
# Layouts
|
|
2
|
-
|
|
3
|
-
Layouts wrap page content in a shared shell — header, footer, navigation, etc. They live in `app/layouts/` and use `<slot>` to inject the page.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Defining a layout
|
|
8
|
-
|
|
9
|
-
```ts
|
|
10
|
-
// app/layouts/default.ts
|
|
11
|
-
component('layout-default', () => {
|
|
12
|
-
return html`
|
|
13
|
-
<header>
|
|
14
|
-
<nav>
|
|
15
|
-
<router-link to="/">Home</router-link>
|
|
16
|
-
<router-link to="/about">About</router-link>
|
|
17
|
-
</nav>
|
|
18
|
-
</header>
|
|
19
|
-
<main>
|
|
20
|
-
<slot></slot>
|
|
21
|
-
</main>
|
|
22
|
-
<footer>
|
|
23
|
-
<p>© 2025 My App</p>
|
|
24
|
-
</footer>
|
|
25
|
-
`
|
|
26
|
-
})
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
The `<slot>` is where the current page's output is injected.
|
|
30
|
-
|
|
31
|
-
---
|
|
32
|
-
|
|
33
|
-
## Naming conventions
|
|
34
|
-
|
|
35
|
-
| File | Layout name | Custom element tag |
|
|
36
|
-
|---|---|---|
|
|
37
|
-
| `app/layouts/default.ts` | `'default'` | `layout-default` |
|
|
38
|
-
| `app/layouts/minimal.ts` | `'minimal'` | `layout-minimal` |
|
|
39
|
-
| `app/layouts/blog/post.ts` | `'blog-post'` | `layout-blog-post` |
|
|
40
|
-
|
|
41
|
-
The **layout name** (the key in the map) is the path relative to `app/layouts/`, with slashes replaced by dashes and the extension stripped:
|
|
42
|
-
- `default.ts` → `'default'`
|
|
43
|
-
- `blog/post.ts` → `'blog-post'`
|
|
44
|
-
|
|
45
|
-
The **tag name** is `layout-` prefixed:
|
|
46
|
-
- `default.ts` → `layout-default`
|
|
47
|
-
- `blog/post.ts` → `layout-blog-post`
|
|
48
|
-
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
## Assigning a layout to a page
|
|
52
|
-
|
|
53
|
-
Set `meta.layout` in any page file:
|
|
54
|
-
|
|
55
|
-
```ts
|
|
56
|
-
// app/pages/about.ts
|
|
57
|
-
component('page-about', () => html`<h1>About</h1>`)
|
|
58
|
-
|
|
59
|
-
export const meta = {
|
|
60
|
-
layout: 'default', // uses app/layouts/default.ts
|
|
61
|
-
}
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
If `meta.layout` is omitted and `app/layouts/default.ts` exists, the default layout is used automatically.
|
|
65
|
-
|
|
66
|
-
To render a page without any layout, explicitly set `layout` to an empty string or `false`:
|
|
67
|
-
|
|
68
|
-
```ts
|
|
69
|
-
export const meta = {
|
|
70
|
-
layout: '', // no layout
|
|
71
|
-
}
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
---
|
|
75
|
-
|
|
76
|
-
## Multiple layouts
|
|
77
|
-
|
|
78
|
-
You can have as many layout files as needed:
|
|
79
|
-
|
|
80
|
-
```
|
|
81
|
-
app/layouts/
|
|
82
|
-
default.ts # full-page layout (header + footer)
|
|
83
|
-
minimal.ts # no header/footer (used for login, error pages)
|
|
84
|
-
dashboard.ts # sidebar + main area
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
Choose per page:
|
|
88
|
-
|
|
89
|
-
```ts
|
|
90
|
-
// app/pages/(auth)/login.ts
|
|
91
|
-
export const meta = { layout: 'minimal' }
|
|
92
|
-
|
|
93
|
-
// app/pages/dashboard/index.ts
|
|
94
|
-
export const meta = { layout: 'dashboard' }
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
---
|
|
98
|
-
|
|
99
|
-
## Accessing layouts in code
|
|
100
|
-
|
|
101
|
-
The layout map is available via `virtual:cer-layouts`:
|
|
102
|
-
|
|
103
|
-
```ts
|
|
104
|
-
import layouts from 'virtual:cer-layouts'
|
|
105
|
-
// { default: 'layout-default', minimal: 'layout-minimal', ... }
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
---
|
|
109
|
-
|
|
110
|
-
## Layout switching and DOM preservation
|
|
111
|
-
|
|
112
|
-
When navigating between pages with different layouts, the framework uses `<cer-keep-alive>` to preserve the layout DOM and avoid unnecessary teardown/remount cycles. This means transitions between pages sharing the same layout are smooth with no layout flash.
|
|
113
|
-
|
|
114
|
-
---
|
|
115
|
-
|
|
116
|
-
## 🪆 Nested layouts
|
|
117
|
-
|
|
118
|
-
Place a `_layout.ts` file inside any page subdirectory to add an inner layout that wraps pages in that subtree. The outer layout (from `meta.layout` or the default) wraps the inner layout, which wraps `<router-view>`.
|
|
119
|
-
|
|
120
|
-
### File convention
|
|
121
|
-
|
|
122
|
-
```
|
|
123
|
-
app/
|
|
124
|
-
layouts/
|
|
125
|
-
default.ts # outer layout — full shell (header, footer)
|
|
126
|
-
minimal.ts # outer layout — bare minimum
|
|
127
|
-
sidebar.ts # inner layout — adds a sidebar panel
|
|
128
|
-
pages/
|
|
129
|
-
index.ts # uses 'default' layout only
|
|
130
|
-
admin/
|
|
131
|
-
_layout.ts # ← inner layout override for all /admin/* pages
|
|
132
|
-
index.ts # layout chain: ['default', 'sidebar']
|
|
133
|
-
users.ts # layout chain: ['default', 'sidebar']
|
|
134
|
-
settings.ts # layout chain: ['default', 'sidebar']
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### `_layout.ts` syntax
|
|
138
|
-
|
|
139
|
-
`_layout.ts` supports two forms:
|
|
140
|
-
|
|
141
|
-
**Legacy — export default string (inner layout only)**
|
|
142
|
-
|
|
143
|
-
```ts
|
|
144
|
-
// app/pages/admin/_layout.ts
|
|
145
|
-
export default 'sidebar'
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
**Group meta — export const meta (middleware + layout defaults)**
|
|
149
|
-
|
|
150
|
-
```ts
|
|
151
|
-
// app/pages/admin/_layout.ts
|
|
152
|
-
export const meta = {
|
|
153
|
-
// All pages in this directory inherit this middleware unless they declare their own
|
|
154
|
-
middleware: ['auth', 'admin'],
|
|
155
|
-
// All pages in this directory use this outer layout by default
|
|
156
|
-
layout: 'admin',
|
|
157
|
-
}
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
You can also mix both forms in the same file:
|
|
161
|
-
|
|
162
|
-
```ts
|
|
163
|
-
// app/pages/admin/_layout.ts
|
|
164
|
-
export default 'sidebar' // inner layout (chain)
|
|
165
|
-
export const meta = {
|
|
166
|
-
middleware: ['auth'], // group middleware
|
|
167
|
-
layout: 'admin', // outer layout override
|
|
168
|
-
}
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
**Precedence rules:**
|
|
172
|
-
- Page-level `meta.middleware` completely overrides group middleware (no merging).
|
|
173
|
-
- Page-level `meta.layout` overrides the group layout default.
|
|
174
|
-
- The group-level `export default` sets the inner layout for the chain — this is never overridden by page meta.
|
|
175
|
-
|
|
176
|
-
The value must match a filename (without extension) in `app/layouts/`.
|
|
177
|
-
|
|
178
|
-
### Rendered structure
|
|
179
|
-
|
|
180
|
-
For a page at `app/pages/admin/users.ts` with the above setup:
|
|
181
|
-
|
|
182
|
-
```html
|
|
183
|
-
<layout-default>
|
|
184
|
-
<layout-sidebar>
|
|
185
|
-
<router-view></router-view>
|
|
186
|
-
</layout-sidebar>
|
|
187
|
-
</layout-default>
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
Each layout receives the inner content via `<slot>`.
|
|
191
|
-
|
|
192
|
-
### Overriding the outer layout
|
|
193
|
-
|
|
194
|
-
If a page in a nested subtree needs a different outer layout, declare it in `meta.layout` as usual:
|
|
195
|
-
|
|
196
|
-
```ts
|
|
197
|
-
// app/pages/admin/login.ts
|
|
198
|
-
export const meta = {
|
|
199
|
-
layout: 'minimal', // overrides outer; chain = ['minimal', 'sidebar']
|
|
200
|
-
}
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
### Multiple nesting levels
|
|
204
|
-
|
|
205
|
-
Nesting is resolved recursively. Each ancestor directory that contains a `_layout.ts` contributes one level to the chain:
|
|
206
|
-
|
|
207
|
-
```
|
|
208
|
-
app/pages/
|
|
209
|
-
admin/
|
|
210
|
-
_layout.ts → 'sidebar'
|
|
211
|
-
settings/
|
|
212
|
-
_layout.ts → 'settings-tabs'
|
|
213
|
-
profile.ts # chain: ['default', 'sidebar', 'settings-tabs']
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
### `meta.layoutChain` in routes
|
|
217
|
-
|
|
218
|
-
The framework emits the resolved chain as `meta.layoutChain` on the route object at build time. You can read it at runtime:
|
|
219
|
-
|
|
220
|
-
```ts
|
|
221
|
-
import routes from 'virtual:cer-routes'
|
|
222
|
-
const adminUsers = routes.find(r => r.path === '/admin/users')
|
|
223
|
-
// adminUsers.meta.layoutChain → ['default', 'sidebar']
|
|
224
|
-
```
|