feat: configure web components declaratively via HTML attributes - #266
Conversation
Add project-id, proxy-path, and url attributes to <zitadel-login> and <zitadel-logout>. Also build the standalone bundle for the browser so it no longer imports node:module.
|
@mridang must be a member of the zitadel team on Vercel to deploy. Learn more about collaboration on Vercel and other options here. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a3c92b5585
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Match the documented precedence: explicit JS config (the project property or the configureZitadel global) wins over project-id/proxy-path/url attributes, so a stale attribute can't override a deliberate global config.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
This PR adds declarative (HTML-attribute) configuration for the <zitadel-login> and <zitadel-logout> orchestrator components, and adjusts the components package’s standalone bundle build so it can be loaded directly in browsers as dist/standalone.mjs.
Changes:
- Add
project-id,proxy-path, andurlattributes to<zitadel-login>/<zitadel-logout>and route them through shared API-resolution logic. - Update the shared
resolveApi()helper to synthesize aZitadelProjectfrom element attributes (while still supportingprojectand global config). - Fix the standalone build output to target the browser platform and keep the
.mjsextension, with unit tests updated/extended accordingly.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/components/tsdown.config.ts | Builds the standalone bundle for platform: "browser" and forces .mjs output naming. |
| packages/components/src/orchestrator/zitadel-logout.ts | Adds declarative config attributes and passes them into resolveApi(). |
| packages/components/src/orchestrator/zitadel-logout.spec.ts | Adds a unit test covering logout configured purely via HTML attributes (no global config). |
| packages/components/src/orchestrator/zitadel-login.ts | Adds declarative config attributes and uses them via resolveApi(); updates error messaging. |
| packages/components/src/orchestrator/zitadel-login.spec.ts | Adds unit tests for attribute-only config and precedence of project property over attributes. |
| packages/components/src/orchestrator/resolve-api.ts | Introduces attribute-based project synthesis and precedence logic for resolving the API client. |
| .changeset/components-declarative-config.md | Adds a changeset describing the new declarative configuration and standalone bundle fix. |
Add a small FIFO bound to the attribute-synthesized project cache so a pathological page can't leak memory. Spell out the full property > global > attributes precedence in the changeset.
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ `main` is currently in **pre mode** so this branch has prereleases rather than normal releases. If you want to exit prereleases, run `changeset pre exit` on `main`.⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ # Releases ## @zitadel/components@0.1.0-alpha.2 ### Minor Changes - [#266](#266) [`01aed1e`](01aed1e) Thanks [@mridang](https://github.com/mridang)! - Allow configuring `<zitadel-login>` and `<zitadel-logout>` declaratively from HTML via `project-id`, `proxy-path`, and `url` attributes, so the components work on a plain page without JS or `configureZitadel()`. Configuration resolves in this order, highest first: the `project` property, then the `configureZitadel()` global, then the HTML attributes. The existing JS paths still win — the attributes are the no-JS fallback. Also fix the standalone bundle so it loads in a browser: it was built for Node and emitted an `import "node:module"` that browsers cannot resolve. It is now built for the browser, so `dist/standalone.mjs` is genuinely self-contained. - [#261](#261) [`09aa2b1`](09aa2b1) Thanks [@mridang](https://github.com/mridang)! - Add a standalone browser bundle (`dist/standalone.mjs`) so the components work on a plain HTML page via `<script type="module">` with no import map or bundler. Exposed via the `./standalone` export and `unpkg`/`jsdelivr`. ### Patch Changes - [#231](#231) [`ce89c59`](ce89c59) Thanks [@bastionstack](https://github.com/bastionstack)! - Tidy the web components package: align README/AGENTS docs with the real SDK-config API, adopt idiomatic Lit patterns (`classMap`, `live()`, `ifDefined`, `@query`, a shared `emit()` helper), make post-step focus deterministic via `updateComplete` instead of `requestAnimationFrame`, centralise SDK/API resolution in a `resolveApi()` helper, correct the manifest registry (e.g. `zl-passkey` `method` attribute), and expand unit/browser test coverage. - [#253](#253) [`c097a5f`](c097a5f) Thanks [@vitorbari](https://github.com/vitorbari)! - Add English labels for the `givenName`, `familyName`, and `dateOfBirth` fields the default register step now collects. ## @zitadel/cli@0.1.0-alpha.2 ### Patch Changes - [#265](#265) [`ceb74d5`](ceb74d5) Thanks [@fforootd](https://github.com/fforootd)! - Derive alpha local runtime images from the installed CLI version, pin generated SDK dependencies to the same alpha train, and emit exact-version follow-up commands for reproducible tester reports. - [#255](#255) [`ca53f61`](ca53f61) Thanks [@fforootd](https://github.com/fforootd)! - Make doctor local-runtime checks advisory for cloud setup, harden fresh Next.js scaffolding, auto-install setup dependencies, normalize public follow-up commands, and avoid assuming Next.js in local-runtime setup guidance. - Updated dependencies [[`b0094f4`](b0094f4)]: - @zitadel/api@0.1.0-alpha.2 ## @zitadel/api@0.1.0-alpha.2 ### Patch Changes - [#268](#268) [`b0094f4`](b0094f4) Thanks [@mridang](https://github.com/mridang)! - Fix `configureZitadel()` so its state survives when more than one copy of `@zitadel/api/config` ends up loaded — the standalone components bundle inlines its own copy, and dual-package hazards / duplicate `node_modules` trees in a monorepo can load a second copy alongside the app's. Previously each module instance held its own `let currentProject`, so a `configureZitadel()` call in one was invisible to `getZitadelConfig()` in another and the components silently saw no config. The slot now lives on `globalThis` under a `Symbol.for(...)` key, which the global symbol registry resolves to the same symbol identity in every copy of the module evaluated in the same JS realm — separate realms (iframes, Node `vm` contexts, worker threads) still have their own registries. ## @zitadel/sdk-angular@0.1.0-alpha.2 ### Patch Changes - Updated dependencies [[`b0094f4`](b0094f4), [`ce89c59`](ce89c59), [`01aed1e`](01aed1e), [`09aa2b1`](09aa2b1), [`c097a5f`](c097a5f)]: - @zitadel/api@0.1.0-alpha.2 - @zitadel/components@0.1.0-alpha.2 ## @zitadel/sdk-next@0.1.0-alpha.2 ### Patch Changes - Updated dependencies [[`b0094f4`](b0094f4), [`ce89c59`](ce89c59), [`01aed1e`](01aed1e), [`09aa2b1`](09aa2b1), [`c097a5f`](c097a5f)]: - @zitadel/api@0.1.0-alpha.2 - @zitadel/components@0.1.0-alpha.2 - @zitadel/sdk-core@0.1.0-alpha.2 ## @zitadel/sdk-nuxt@0.1.0-alpha.2 ### Patch Changes - Updated dependencies [[`b0094f4`](b0094f4), [`ce89c59`](ce89c59), [`01aed1e`](01aed1e), [`09aa2b1`](09aa2b1), [`c097a5f`](c097a5f)]: - @zitadel/api@0.1.0-alpha.2 - @zitadel/components@0.1.0-alpha.2 - @zitadel/sdk-core@0.1.0-alpha.2 ## @zitadel/sdk-react@0.1.0-alpha.2 ### Patch Changes - Updated dependencies [[`b0094f4`](b0094f4), [`ce89c59`](ce89c59), [`01aed1e`](01aed1e), [`09aa2b1`](09aa2b1), [`c097a5f`](c097a5f)]: - @zitadel/api@0.1.0-alpha.2 - @zitadel/components@0.1.0-alpha.2 - @zitadel/sdk-core@0.1.0-alpha.2 ## @zitadel/sdk-vue@0.1.0-alpha.2 ### Patch Changes - Updated dependencies [[`b0094f4`](b0094f4), [`ce89c59`](ce89c59), [`01aed1e`](01aed1e), [`09aa2b1`](09aa2b1), [`c097a5f`](c097a5f)]: - @zitadel/api@0.1.0-alpha.2 - @zitadel/components@0.1.0-alpha.2 - @zitadel/sdk-core@0.1.0-alpha.2 ## @zitadel/sdk-core@0.1.0-alpha.2 Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Configure
<zitadel-login>and<zitadel-logout>from HTML viaproject-id,proxy-path, andurlattributes, so they work on a plain page with no JS and noconfigureZitadel(). Theprojectproperty and the global config still win, in that order.Also fixes the standalone bundle from #261, which was built for Node and emitted an
import "node:module"that browsers reject. It now builds for the browser, sodist/standalone.mjsloads as a plain module script.Verified with 150 unit tests and in a real browser.