Skip to content

feat: SSR compatibility PoC for journey-client and oidc-client#566

Draft
ryanbas21 wants to merge 1 commit intomainfrom
ssr-jc
Draft

feat: SSR compatibility PoC for journey-client and oidc-client#566
ryanbas21 wants to merge 1 commit intomainfrom
ssr-jc

Conversation

@ryanbas21
Copy link
Copy Markdown
Collaborator

Summary

This is a complete proof of concept — not finished work. It demonstrates the changes needed to make journey-client and oidc-client work in server-side rendering environments (SvelteKit, Next.js, etc.).

Problem

  • @forgerock/storage eagerly references sessionStorage/localStorage globals, crashing on import in Node.js
  • createAuthorizeUrl couples PKCE generation with sessionStorage, preventing server-side authorize URL creation
  • window.location.assign() in redirect() has no server guard

Changes

Storage (@forgerock/storage)

  • Replace eager browser global references with lazy globalThis access via getBrowserStorage()
  • SSR callers use existing type: 'custom' with a no-op adapter — no new types needed

Journey Client (@forgerock/journey-client)

  • Add optional storage config to JourneyClientConfig (defaults to sessionStorage)
  • Guard redirect() with typeof window check
  • Export createJourneyObject for client-side step reconstitution after SSR

OIDC / PKCE (@forgerock/sdk-oidc, @forgerock/oidc-client)

  • Decouple PKCE generation from storage — createAuthorizeUrl now returns { url, verifier, state } instead of writing to sessionStorage
  • Callers persist PKCE values however they choose (cookies, server session, etc.)
  • token.exchange() accepts optional pkceValues parameter to skip sessionStorage lookup
  • Browser background flow still uses sessionStorage internally (unchanged behavior)

SvelteKit PoC (e2e/svelte-app)

  • Demonstrates full end-to-end flow against the AM mock API:
    1. Server-side journey start() → SSR-rendered login form
    2. Client-side credential submission via next()
    3. Server-side PKCE authorize URL generation with cookie-based verifier persistence
    4. Server-side token exchange → tokens received

Test plan

  • nx run storage:test — 21 tests pass
  • nx run journey-client:test — 193 tests pass
  • nx run sdk-oidc:test — 26 tests pass
  • nx run oidc-client:test — 21 tests pass
  • nx run davinci-client:test — 226 tests pass
  • SvelteKit PoC: start am-mock-api:serve + vite dev in e2e/svelte-app, verify SSR rendering and token exchange

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 9, 2026

⚠️ No Changeset found

Latest commit: 3088dc6

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 9, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4fe3fd10-77ba-44df-abce-ebfee8d1d9bc

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ssr-jc

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Make journey-client and oidc-client importable and usable in Node.js/SSR
environments by eliminating eager browser global references and decoupling
PKCE generation from sessionStorage.

Storage: Replace eager sessionStorage/localStorage references with lazy
globalThis access via getBrowserStorage(). Add configurable storage option
to JourneyClientConfig so SSR callers can provide a custom noop adapter.

PKCE: Decouple generation from storage — createAuthorizeUrl now returns
{ url, verifier, state } instead of writing to sessionStorage. Callers
persist PKCE values however they choose (cookies, server session, etc.).
Token exchange accepts optional pkceValues parameter to skip sessionStorage.

Guard redirect() with typeof window check for server environments.
Export createJourneyObject for client-side step reconstitution.

SvelteKit PoC in e2e/svelte-app demonstrates the full flow:
server-side journey start, client-side credential submission,
server-side PKCE authorize URL generation with cookie-based verifier
persistence, and server-side token exchange against the AM mock API.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant