Skip to content

Add webjs.clientRouter:false opt-out for the automatic client router #629

Description

@vivek7405

Problem

As of #620 the client router auto-enables whenever @webjsdev/core loads in the browser (any page that ships a component), and layouts no longer import @webjsdev/core/client-router. That removed the only de-facto opt-out an app had (omitting the import). An app that genuinely wants pure MPA / full-page navigation despite shipping interactive components now has no declarative way to turn the router off.

This is intentionally deferred from #620 (no users to break yet, and automatic navigation is the stated thesis), but it should exist before external adoption.

Design / approach

A package.json webjs.clientRouter: false config key (default true). Because the auto-enable runs in the shared webjs-core-browser.js bundle (client-side), the server must communicate the opt-out to the browser:

  • Server reads webjs.clientRouter (the standard webjs.* 3-place lockstep: schema + WebjsConfig type + a reader), and when false emits a tiny inline signal BEFORE the boot module script (e.g. <script>window.__webjs_no_router__=true</script>, or a <html data-webjs-no-router> attribute) so it is set before the deferred module bundle evaluates.
  • The router's module-end auto-enable (packages/core/src/router-client.js) guards on that signal: if (no-router flag) return; instead of calling enableClientRouter().
  • disableClientRouter() stays the programmatic escape hatch.

Implementation notes (for the implementing agent)

  • Config (server AGENTS.md "The webjs package.json config block", 3 places + drift test): packages/server/webjs-config.schema.json, packages/core/src/webjs-config.d.ts (WebjsConfig), a reader (e.g. in dev.js), and KNOWN_KEYS in test/config/webjs-config-schema.test.js.
  • Emit seam: ssr.js boot/shell assembly (it already emits the importmap + WEBJS_PUBLIC_ inline script + boot module). The flag must be in the document BEFORE the boot <script type="module"> (module scripts are deferred, so an inline classic script in <head>/early <body> runs first).
  • Router gate: packages/core/src/router-client.js module-end enableClientRouter() call (added/made explicit in dogfood: auto-enable client router via webjs-core-browser.js, drop layout imports #620 via index-browser.js). Read the flag with a typeof window guard.
  • Tests: a browser/unit test that the flag suppresses the auto-enable (counterfactual: absent flag enables); a config drift test; an e2e/integration asserting webjs.clientRouter:false yields full-page navigation.
  • Docs: the client-router doc page + AGENTS.md (note the opt-out), once it lands.
  • Invariant: the DEFAULT (absent / any non-false value) must be byte-identical to today's automatic-on behaviour.

Acceptance criteria

  • webjs.clientRouter: false disables the client-router auto-enable (full-page navigation), config wired in schema + type + reader + drift test
  • Default and any non-false value keep the router automatic (unchanged)
  • The flag is emitted before the boot module so it is honored on first load
  • Browser/e2e test proves both states, with a counterfactual
  • Docs note the opt-out

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

  • Status
    Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions