SDKS-5067: Standardize SDK Configuration#118
Conversation
📝 WalkthroughWalkthroughThree React todo sample apps (davinci, journey, oidc) migrate OIDC/SDK configuration from individual environment variables ( ChangesSDK Config Migration to config.json
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
javascript/reactjs-todo-journey/client/components/journey/journey.hook.jsOops! Something went wrong! :( ESLint: 8.57.1 Error: ESLint configuration in --config is invalid:
javascript/reactjs-todo-journey/client/constants.jsOops! Something went wrong! :( ESLint: 8.57.1 Error: ESLint configuration in --config is invalid:
javascript/reactjs-todo-journey/client/context/oidc.context.jsOops! Something went wrong! :( ESLint: 8.57.1 Error: ESLint configuration in --config is invalid:
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. Comment |
vatsalparikh
left a comment
There was a problem hiding this comment.
We should update reactjs-todo-login-widget's configuration too
feffca3 to
363e5dc
Compare
feat(reactjs-todo-oidc): migrate SDK config to config.json feat(reactjs-todo-journey): migrate SDK config to config.json feat(sample-apps): inject SDK config via env var for e2e, fall back to config.json fix(reactjs-todo-davinci): migrate fido playwright block to unified config fix(reactjs-todo-journey): replace deprecated assert with import attribute fix(reactjs-todo-oidc): remove REST_OAUTH vars from env.example, add CI clarification docs: update README setup sections to reflect config.json migration feat(reactjs-todo-davinci): wire make*Config from sdk-utilities feat(reactjs-todo-oidc): wire makeOidcConfig from sdk-utilities feat(reactjs-todo-journey): wire make*Config from sdk-utilities fix(sample-apps): derive redirectUri dynamically from window.location.origin
The login widget app uses |
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
javascript/reactjs-todo-davinci/client/context/oidc.context.js (1)
34-63:⚠️ Potential issue | 🟠 Major | ⚡ Quick winMissing
jsonin useEffect dependency array.The
useEffectat line 34 uses thejsonparameter insideinitOidcClient()(line 48) but omitsjsonfrom the dependency array at line 63. This breaks the React hook contract: ifjsonchanges, the OIDC client will not be re-initialized with the new configuration. Thereactjs-todo-journeyversion of this file correctly includes[json, oidcClient].[major]
🔧 Proposed fix: Add `json` to the dependency array
}, [oidcClient]); + }, [json, oidcClient]);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@javascript/reactjs-todo-davinci/client/context/oidc.context.js` around lines 34 - 63, The useEffect hook starting at line 34 uses the json parameter inside the initOidcClient function when calling makeOidcConfig(json), but json is missing from the dependency array at line 63. Add json to the dependency array alongside oidcClient so that when json changes, the OIDC client will be re-initialized with the new configuration, ensuring the React hook contract is followed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@javascript/reactjs-todo-davinci/client/constants.js`:
- Line 29: The rawConfig constant assignment does not handle errors when parsing
process.env.SDK_CONFIG, which will cause the entire module to fail loading if
the JSON is malformed. Wrap the JSON.parse call in a try-catch block, and if
parsing throws an error, fall back to using sdkConfigJson as the default value.
This ensures the application can still initialize even when SDK_CONFIG contains
invalid JSON.
In `@javascript/reactjs-todo-davinci/playwright.config.ts`:
- Line 3: The import statement for testFidoConfig is triggering a no-unused-vars
lint error because the variable is only referenced in commented code and not
actively used. Either remove the import statement for testFidoConfig entirely if
it is not needed, or uncomment and properly integrate the code that uses
testFidoConfig so the variable is actively referenced in the configuration.
In `@javascript/reactjs-todo-davinci/README.md`:
- Around line 65-70: The README.md file contains an inconsistency in the
redirect URI configuration examples, showing
https://localhost:8443/callback.html in one location and
http://localhost:8443/callback.html in another. Update the redirect URI in the
OIDC configuration example to use the same protocol (http or https) consistently
throughout the entire README file to prevent configuration errors during user
onboarding.
In `@javascript/reactjs-todo-journey/client/constants.js`:
- Around line 31-33: The JSON parsing of environment variables can cause module
load-time crashes if the JSON is malformed. In
javascript/reactjs-todo-journey/client/constants.js lines 31-33, wrap the
JSON.parse call for import.meta.env.VITE_SDK_CONFIG in a try/catch block and
fallback to sdkConfigJson on parse failure. Apply the same guarded
parse/fallback pattern in javascript/reactjs-todo-oidc/client/constants.js line
28 for process.env.SDK_CONFIG to ensure both modules gracefully handle invalid
JSON without crashing at load time.
- Around line 35-40: The CONFIG object in both files unconditionally overwrites
the redirectUri property, ignoring any pre-configured value from rawConfig. In
javascript/reactjs-todo-journey/client/constants.js at lines 35-40, modify the
oidc.redirectUri assignment to conditionally use the value from
rawConfig.oidc.redirectUri when it exists, falling back to the
window.location.origin-based URL only when it is missing or undefined. Apply the
identical conditional fallback pattern to
javascript/reactjs-todo-oidc/client/constants.js at lines 30-35 so that any
configured redirect URI in rawConfig is preserved instead of being clobbered.
In `@javascript/reactjs-todo-journey/vite.config.js`:
- Line 44: The current code uses new URL(...).pathname to construct a file path
for the config.json file, which is unreliable on Windows and other platforms due
to leading slashes and unencoded characters. Import the fileURLToPath function
from the built-in url module and replace the pathname-based approach in the
optionalConfigJson call with fileURLToPath(new URL('./config.json',
import.meta.url)) to ensure the path works correctly across all platforms when
checked by existsSync.
---
Outside diff comments:
In `@javascript/reactjs-todo-davinci/client/context/oidc.context.js`:
- Around line 34-63: The useEffect hook starting at line 34 uses the json
parameter inside the initOidcClient function when calling makeOidcConfig(json),
but json is missing from the dependency array at line 63. Add json to the
dependency array alongside oidcClient so that when json changes, the OIDC client
will be re-initialized with the new configuration, ensuring the React hook
contract is followed.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 809bdce5-7376-4f24-8136-1a1fa2a83af3
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (36)
javascript/reactjs-todo-davinci/.env.examplejavascript/reactjs-todo-davinci/.gitignorejavascript/reactjs-todo-davinci/README.mdjavascript/reactjs-todo-davinci/client/components/davinci-client/hooks/create-client.utils.jsjavascript/reactjs-todo-davinci/client/constants.jsjavascript/reactjs-todo-davinci/client/context/oidc.context.jsjavascript/reactjs-todo-davinci/config.example.jsonjavascript/reactjs-todo-davinci/config.test.fido.jsonjavascript/reactjs-todo-davinci/config.test.jsonjavascript/reactjs-todo-davinci/package.jsonjavascript/reactjs-todo-davinci/playwright.config.tsjavascript/reactjs-todo-davinci/webpack.config.jsjavascript/reactjs-todo-journey/.env.examplejavascript/reactjs-todo-journey/.gitignorejavascript/reactjs-todo-journey/README.mdjavascript/reactjs-todo-journey/client/components/journey/journey.hook.jsjavascript/reactjs-todo-journey/client/constants.jsjavascript/reactjs-todo-journey/client/context/oidc.context.jsjavascript/reactjs-todo-journey/config.example.jsonjavascript/reactjs-todo-journey/config.test.jsonjavascript/reactjs-todo-journey/e2e/embedded-login.spec.jsjavascript/reactjs-todo-journey/package.jsonjavascript/reactjs-todo-journey/playwright.config.jsjavascript/reactjs-todo-journey/vite.config.jsjavascript/reactjs-todo-oidc/.env.examplejavascript/reactjs-todo-oidc/.gitignorejavascript/reactjs-todo-oidc/README.mdjavascript/reactjs-todo-oidc/client/README.mdjavascript/reactjs-todo-oidc/client/constants.jsjavascript/reactjs-todo-oidc/client/context/oidc.context.jsjavascript/reactjs-todo-oidc/config.example.jsonjavascript/reactjs-todo-oidc/config.test.pingam.jsonjavascript/reactjs-todo-oidc/config.test.pingone.jsonjavascript/reactjs-todo-oidc/package.jsonjavascript/reactjs-todo-oidc/playwright.config.tsjavascript/reactjs-todo-oidc/webpack.config.js
| * PingOne environment, used to resolve authorization/token endpoints | ||
| *************************************************************************** */ | ||
|
|
||
| const rawConfig = process.env.SDK_CONFIG ? JSON.parse(process.env.SDK_CONFIG) : sdkConfigJson; |
There was a problem hiding this comment.
Guard SDK_CONFIG parsing to prevent startup-time crashes.
Line 29 parses process.env.SDK_CONFIG without error handling; malformed JSON will throw during module load and hard-fail app initialization.
Proposed fix
-import sdkConfigJson from '../config.json';
+import sdkConfigJson from '../config.json';
@@
-const rawConfig = process.env.SDK_CONFIG ? JSON.parse(process.env.SDK_CONFIG) : sdkConfigJson;
+const rawConfig = (() => {
+ if (!process.env.SDK_CONFIG) return sdkConfigJson;
+ try {
+ return JSON.parse(process.env.SDK_CONFIG);
+ } catch (error) {
+ throw new Error(`Invalid SDK_CONFIG JSON: ${error.message}`);
+ }
+})();🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@javascript/reactjs-todo-davinci/client/constants.js` at line 29, The
rawConfig constant assignment does not handle errors when parsing
process.env.SDK_CONFIG, which will cause the entire module to fail loading if
the JSON is malformed. Wrap the JSON.parse call in a try-catch block, and if
parsing throws an error, fall back to using sdkConfigJson as the default value.
This ensures the application can still initialize even when SDK_CONFIG contains
invalid JSON.
| @@ -1,4 +1,6 @@ | |||
| import { defineConfig, devices } from '@playwright/test'; | |||
| import testConfig from './config.test.json'; | |||
| import testFidoConfig from './config.test.fido.json'; | |||
There was a problem hiding this comment.
Remove or use testFidoConfig to fix the lint error.
testFidoConfig is currently unused because the only reference is inside commented code, which triggers no-unused-vars.
💡 Suggested fix
import { defineConfig, devices } from '`@playwright/test`';
import testConfig from './config.test.json';
-import testFidoConfig from './config.test.fido.json';📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import testFidoConfig from './config.test.fido.json'; | |
| import { defineConfig, devices } from '`@playwright/test`'; | |
| import testConfig from './config.test.json'; |
🧰 Tools
🪛 ESLint
[error] 3-3: 'testFidoConfig' is defined but never used.
(no-unused-vars)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@javascript/reactjs-todo-davinci/playwright.config.ts` at line 3, The import
statement for testFidoConfig is triggering a no-unused-vars lint error because
the variable is only referenced in commented code and not actively used. Either
remove the import statement for testFidoConfig entirely if it is not needed, or
uncomment and properly integrate the code that uses testFidoConfig so the
variable is actively referenced in the configuration.
Source: Linters/SAST tools
| "oidc": { | ||
| "clientId": "<your-oauth-client-id>", | ||
| "discoveryEndpoint": "https://<your-domain>/.well-known/openid-configuration", | ||
| "scopes": ["openid", "profile", "email"], | ||
| "redirectUri": "https://localhost:8443/callback.html" | ||
| } |
There was a problem hiding this comment.
Fix redirect URI protocol mismatch in setup instructions.
Line 69 shows https://localhost:8443/callback.html, but the same README config/setup path uses http://localhost:8443/callback.html (Line 41). Align these to one value to avoid misconfiguration during onboarding.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@javascript/reactjs-todo-davinci/README.md` around lines 65 - 70, The
README.md file contains an inconsistency in the redirect URI configuration
examples, showing https://localhost:8443/callback.html in one location and
http://localhost:8443/callback.html in another. Update the redirect URI in the
OIDC configuration example to use the same protocol (http or https) consistently
throughout the entire README file to prevent configuration errors during user
onboarding.
| const rawConfig = import.meta.env.VITE_SDK_CONFIG | ||
| ? JSON.parse(import.meta.env.VITE_SDK_CONFIG) | ||
| : sdkConfigJson; |
There was a problem hiding this comment.
Both constants modules can hard-crash on malformed SDK_CONFIG JSON due to unguarded parse at module load.
javascript/reactjs-todo-journey/client/constants.js#L31-L33: wrap env JSON parsing intry/catchand fallback tosdkConfigJsonon parse failure.javascript/reactjs-todo-oidc/client/constants.js#L28-L28: apply the same guarded parse/fallback pattern forprocess.env.SDK_CONFIG.
📍 Affects 2 files
javascript/reactjs-todo-journey/client/constants.js#L31-L33(this comment)javascript/reactjs-todo-oidc/client/constants.js#L28-L28
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@javascript/reactjs-todo-journey/client/constants.js` around lines 31 - 33,
The JSON parsing of environment variables can cause module load-time crashes if
the JSON is malformed. In javascript/reactjs-todo-journey/client/constants.js
lines 31-33, wrap the JSON.parse call for import.meta.env.VITE_SDK_CONFIG in a
try/catch block and fallback to sdkConfigJson on parse failure. Apply the same
guarded parse/fallback pattern in
javascript/reactjs-todo-oidc/client/constants.js line 28 for
process.env.SDK_CONFIG to ensure both modules gracefully handle invalid JSON
without crashing at load time.
| export const CONFIG = { | ||
| clientId: WEB_OAUTH_CLIENT, | ||
| redirectUri: `${window.location.origin}/callback.html`, | ||
| scope: SCOPE, | ||
| serverConfig: { | ||
| wellknown: WELLKNOWN_URL, | ||
| ...rawConfig, | ||
| oidc: { | ||
| ...rawConfig.oidc, | ||
| redirectUri: `${window.location.origin}/callback.html`, | ||
| }, |
There was a problem hiding this comment.
The unified config’s oidc.redirectUri is ignored in both apps because it is always overwritten.
javascript/reactjs-todo-journey/client/constants.js#L35-L40: preserverawConfig.oidc.redirectUriwhen present, and only fallback to${window.location.origin}/callback.htmlwhen missing.javascript/reactjs-todo-oidc/client/constants.js#L30-L35: apply the same conditional fallback to avoid clobbering configured redirect URIs.
📍 Affects 2 files
javascript/reactjs-todo-journey/client/constants.js#L35-L40(this comment)javascript/reactjs-todo-oidc/client/constants.js#L30-L35
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@javascript/reactjs-todo-journey/client/constants.js` around lines 35 - 40,
The CONFIG object in both files unconditionally overwrites the redirectUri
property, ignoring any pre-configured value from rawConfig. In
javascript/reactjs-todo-journey/client/constants.js at lines 35-40, modify the
oidc.redirectUri assignment to conditionally use the value from
rawConfig.oidc.redirectUri when it exists, falling back to the
window.location.origin-based URL only when it is missing or undefined. Apply the
identical conditional fallback pattern to
javascript/reactjs-todo-oidc/client/constants.js at lines 30-35 so that any
configured redirect URI in rawConfig is preserved instead of being clobbered.
| strictPort: true, | ||
| }, | ||
| plugins: [react()], | ||
| plugins: [react(), optionalConfigJson(new URL('./config.json', import.meta.url).pathname)], |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Find the vite.config.js file
fd -t f "vite.config.js"Repository: ForgeRock/sdk-sample-apps
Length of output: 177
🏁 Script executed:
# Read the vite.config.js file to see the full context
cat -n javascript/reactjs-todo-journey/vite.config.jsRepository: ForgeRock/sdk-sample-apps
Length of output: 1852
🏁 Script executed:
# Search for the optionalConfigJson function definition
rg -n "optionalConfigJson" --type jsRepository: ForgeRock/sdk-sample-apps
Length of output: 306
🌐 Web query:
fileURLToPath vs URL.pathname Node.js filesystem Windows
💡 Result:
You should always use fileURLToPath instead of URL.pathname when converting a file URL to a file system path in Node.js, particularly for cross-platform compatibility [1][2][3]. Using URL.pathname directly on Windows is problematic and will lead to errors because it treats the URL as a generic URI rather than a native file system path [4][5][3]. Specifically: 1. Incorrect Path Formatting: On Windows, a file URL like file:///C:/path/results in a pathname of /C:/path/ [1][2][3]. This leading slash causes Windows file system APIs to interpret the path as being relative to the current drive, often resulting in invalid paths like C:\C:\path\ [1][3]. 2. Lack of Decoding: URL.pathname does not correctly decode percent-encoded characters [2][6]. Characters like spaces (%20) or non-ASCII characters remain encoded, which prevents native file system modules (like fs) from locating the files correctly [5][2]. 3. Handling of UNC Paths: URL.pathname fails to correctly represent Windows UNC paths (e.g., file://nas/share), stripping important host information that fileURLToPath preserves as \nas\share [2][6]. In contrast, fileURLToPath from the node:url module is designed to handle these platform-specific differences [2][7]. It ensures that the output is a correctly formatted, absolute path string for the host operating system, handles percent-decoding, and correctly manages drive letters and UNC paths [2][7][6]. Whenever you need to convert an import.meta.url or other file URL into a path for operations like fs.readFileSync, use the following pattern: import { fileURLToPath } from 'node:url'; const filePath = fileURLToPath(import.meta.url);
Citations:
- 1: https://bero.dev/dont-use-url-to-construct-paths-in-node-js/
- 2: nodejs/node@5553be3f4e
- 3: https://cirrus.twiddles.com/blog/2024/08/20/fixing-node-js-paths-on-windows/
- 4: new URL('.', import.meta.url).pathname produces erroneous path on Windows 10 nodejs/node#37845
- 5: Discussion: File URLs in Node.js nodejs/node#22502
- 6: https://beta.docs.nodejs.org/url.html
- 7: https://nodejs.org/api/url.html
🏁 Script executed:
# Check if there are other instances of this pattern in the codebase
rg "new URL.*import.meta.url.*pathname" --type jsRepository: ForgeRock/sdk-sample-apps
Length of output: 212
Use fileURLToPath for the config file path check.
Passing new URL(...).pathname into existsSync is unreliable on Windows and other platforms. On Windows, URL.pathname adds a leading slash that produces invalid paths (e.g., /C:/path), and it fails to decode percent-encoded characters. This causes existsSync to incorrectly return false even when the file exists, forcing the empty virtual module fallback.
💡 Suggested fix
import { defineConfig, loadEnv } from 'vite';
import react from '`@vitejs/plugin-react`';
import { existsSync } from 'fs';
+import { fileURLToPath } from 'url';
@@
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), '');
const PORT = parseInt(env.VITE_PORT) || 8443;
+ const configJsonPath = fileURLToPath(new URL('./config.json', import.meta.url));
@@
- plugins: [react(), optionalConfigJson(new URL('./config.json', import.meta.url).pathname)],
+ plugins: [react(), optionalConfigJson(configJsonPath)],🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@javascript/reactjs-todo-journey/vite.config.js` at line 44, The current code
uses new URL(...).pathname to construct a file path for the config.json file,
which is unreliable on Windows and other platforms due to leading slashes and
unencoded characters. Import the fileURLToPath function from the built-in url
module and replace the pathname-based approach in the optionalConfigJson call
with fileURLToPath(new URL('./config.json', import.meta.url)) to ensure the path
works correctly across all platforms when checked by existsSync.
You're right, my bad. Login widget is unrelated here. |
Summary
https://pingidentity.atlassian.net/browse/SDKS-5067
Migrates SDK credentials out of environment variables and into a per-app
config.jsonfile using the unified SDK configuration schema. All threeJavaScript sample apps (reactjs-todo-davinci, reactjs-todo-oidc,
reactjs-todo-journey) now accept a structured JSON config object detected and
mapped to internal config automatically by the factory discriminator.
Changes
reactjs-todo-davinciconstants.js— replacesWEB_OAUTH_CLIENT/SCOPE/WELLKNOWN_URLenvvars with
CONFIGimported fromconfig.json; falls back toSDK_CONFIGenv var (JSON string) for e2e/CI
config.example.json— new committed template for the unified SDK configshape
config.test.json/config.test.fido.json— committed test fixturesreplacing hardcoded Playwright env vars
playwright.config.ts— usesSDK_CONFIG: JSON.stringify(testConfig)instead of individual credential vars
webpack.config.js— removesWEB_OAUTH_CLIENT/SCOPE/WELLKNOWN_URL;injects
SDK_CONFIG.env.example— removes SDK credential vars; adds migration note.gitignore— addsconfig.jsonreactjs-todo-oidcconstants.js— same pattern as davinci; preservesSERVERenv var(PingAM/PingOne display-name logic)
config.example.json— new committed templateconfig.test.pingam.json/config.test.pingone.json— per-server testfixtures
playwright.config.ts— usesSDK_CONFIGper project configwebpack.config.js— same removals/additions as davinci.env.example,.gitignore,README.md,client/README.md— updatedreactjs-todo-journeyconstants.js— Vite JSON import (import.meta.env.VITE_SDK_CONFIGoverride for CI)
config.example.json— new committed templateconfig.test.json— committed test fixtureplaywright.config.js— usesVITE_SDK_CONFIG: JSON.stringify(testConfig).env.example,.gitignore,README.md— updatedTests
SDK_CONFIG/VITE_SDK_CONFIGinjection patternpre-existing
babel-loader/validateOptionsfailure atbc9ebefunrelatedto this change)
How to test
1. Local dev setup
Copy
config.example.json→config.jsonin each app root, fill inclientId,discoveryEndpoint,scopes,redirectUri. Copy.env.example→
.env, fill remaining runtime vars. Runnpm run start:reactjs-todo-dv(or journey/oidc variant) from
javascript/. Verify auth flow completes.2. E2E run
Run
npm run e2e --workspace reactjs-todo-davinci,--workspace reactjs-todo-journey, and--workspace reactjs-todo-oidcfromjavascript/. All suites should pass. Confirmconfig.jsonis not committed(gitignored).
3. Verify backward-compat
Confirm no
WEB_OAUTH_CLIENT,SCOPE, orWELLKNOWN_URL(orVITE_variants) remain in
.env.example,webpack.config.js, or Playwrightconfigs.
Summary by CodeRabbit
Release Notes
Documentation
.envexamples to focus only on runtime settings (API URL, debug flags, port).Chores