Skip to content

feat: support custom share URL base for embedded configurator - #174

Merged
jackgranatowski merged 2 commits into
mainfrom
claude/mobile-configurator-ui-tp5nhk
Jul 7, 2026
Merged

jackgranatowski merged 2 commits into
mainfrom
claude/mobile-configurator-ui-tp5nhk

Conversation

@jackgranatowski

Copy link
Copy Markdown
Contributor

Summary

Adds support for a configurable share URL base when the configurator is embedded in a host application (e.g., WordPress plugin). This allows embedded instances to generate share links pointing to a public standalone configurator URL instead of the logged-in admin page.

Key changes:

  • Add getShareBaseUrl() function to retrieve the configurator URL from plugin settings
  • Pass overrides object to StudioHeader and use it to build proper share URLs via buildShareUrl(overrides, getShareBaseUrl())
  • Update ExportPanel to use the same share URL builder
  • Improve responsive layout in header: hide text labels on small screens, add horizontal scroll container with shrink-0 utilities
  • Update vendored manifest to reflect local source (sync timestamp updated)

The share URL generation now respects the embedded host's public configurator URL when available, falling back to the current page URL in standalone mode.

Type

  • feat
  • fix
  • docs
  • chore / tooling

Checklist

  • Conventional Commit messages (feat:, fix:, docs:, …)
  • npm test passes
  • npm run lint passes (stylelint + php -l)
  • npm run verify passes (version metadata in sync)
  • Generated artifacts not hand-edited (dist/, data/inventory.json, data/classes-hints.json come from update-framework / build:data)
  • CHANGELOG.md updated under ## [Unreleased] (for user-facing changes)
  • Built SPA assets committed if editor-app/admin-app source changed

Notes

Changes are isolated to plugin-specific files (admin-app/src/App.svelte, admin-app/src/lib/persistence.ts, admin-app/src/components/panels/ExportPanel.svelte, admin-app/src/components/shell/StudioHeader.svelte, admin-app/src/vite-env.d.ts) and do not affect vendored framework code. The responsive header improvements ensure the UI remains usable on smaller screens when embedded.

https://claude.ai/code/session_01QTPpAk2ynC74tuUAsVpYNf

Pulls in codeslash-dev/SLASHED@b6f1f20: the header's button cluster now
fits/scrolls on narrow viewports instead of pushing the light/dark
toggle off-screen, and the Share button builds a proper config-code
link instead of copying the raw page URL. In the plugin specifically,
share links now point at the public standalone configurator
(configurator_url, already localized as window.slashedApp.pluginSettings)
instead of the logged-in wp-admin URL, since overrides here persist via
REST rather than the URL hash.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QTPpAk2ynC74tuUAsVpYNf
@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@jackgranatowski, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 40 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 160f40ea-1133-4b16-8963-a091418aa2e4

📥 Commits

Reviewing files that changed from the base of the PR and between 79bb700 and 688e266.

📒 Files selected for processing (8)
  • SLASHED-for-WP/admin-app/.vendored-manifest.json
  • SLASHED-for-WP/admin-app/src/App.svelte
  • SLASHED-for-WP/admin-app/src/components/panels/ExportPanel.svelte
  • SLASHED-for-WP/admin-app/src/components/shell/StudioHeader.svelte
  • SLASHED-for-WP/admin-app/src/lib/persistence.ts
  • SLASHED-for-WP/admin-app/src/vite-env.d.ts
  • SLASHED-for-WP/assets/admin-app/app.css
  • SLASHED-for-WP/assets/admin-app/app.js
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/mobile-configurator-ui-tp5nhk

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.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Support configurable share URL base for embedded configurator

✨ Enhancement ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Generate share links against a host-provided base URL when running embedded.
• Use the same share URL builder in both the header Share button and Export panel.
• Improve header responsiveness on small screens via horizontal scrolling and hidden text labels.
Diagram

graph TD
  A{{"Embedded host"}} --> B["window.slashedApp"] --> C["persistence.ts"] --> D["getShareBaseUrl()"] --> E["codec.ts"] --> F["buildShareUrl()"] --> G["StudioHeader"]
  F --> H["ExportPanel"]
  subgraph Legend
    direction LR
    _ext{{"External/Host"}} ~~~ _mod["Module" ] ~~~ _ui["UI component"]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Pass shareBaseUrl as an explicit prop from App.svelte
  • ➕ Keeps StudioHeader/ExportPanel pure and easier to test (no global reads).
  • ➕ Centralizes embedded-vs-standalone decisions in one place (root composition).
  • ➖ Requires additional wiring through component props.
  • ➖ Still needs a single source of truth that reads host settings somewhere.
2. Introduce a single share-link helper (e.g., share.ts) that encapsulates base resolution
  • ➕ Removes repeated getShareBaseUrl() calls at each call site.
  • ➕ Creates one canonical API for future share behaviors (query params, analytics, etc.).
  • ➖ Potential over-abstraction for only two call sites today.
  • ➖ Adds another module boundary to navigate during debugging.

Recommendation: The PR’s approach is a good fit for the current scope: getShareBaseUrl() is a small, well-documented adapter over host boot settings, and callers consistently use buildShareUrl(overrides, base). If sharing requirements expand, consider consolidating share URL construction behind a single helper to keep UI components thinner.

Files changed (8) +123 / -101

Enhancement (4) +42 / -21
persistence.tsAdd base-aware share URL helper for embedded hosts +15/-0

Add base-aware share URL helper for embedded hosts

• Extends the embedded boot payload typing to include plugin settings and introduces 'getShareBaseUrl()' to return a public configurator URL when provided by the host. This prevents embedded share links from pointing at logged-in admin pages while preserving standalone behavior via fallback.

SLASHED-for-WP/admin-app/src/lib/persistence.ts

StudioHeader.svelteBuild share links from overrides + host base URL; improve mobile layout +24/-20

Build share links from overrides + host base URL; improve mobile layout

• Updates the Share button to copy a generated share URL using 'buildShareUrl(overrides, getShareBaseUrl())' instead of copying 'window.location.href'. Also makes the header button cluster horizontally scrollable on narrow screens and hides verbose button text on small viewports.

SLASHED-for-WP/admin-app/src/components/shell/StudioHeader.svelte

ExportPanel.svelteUse host-aware share URL builder in Export panel +2/-1

Use host-aware share URL builder in Export panel

• Switches the 'Copy shareable link' action to pass 'getShareBaseUrl()' into 'buildShareUrl(...)', aligning share behavior with the header and embedded-host expectations.

SLASHED-for-WP/admin-app/src/components/panels/ExportPanel.svelte

App.sveltePass overrides into StudioHeader for share URL generation +1/-0

Pass overrides into StudioHeader for share URL generation

• Wires the current 'overrides' object into 'StudioHeader' so the header can generate a correct share link for the current configuration state.

SLASHED-for-WP/admin-app/src/App.svelte

Other (4) +81 / -80
vite-env.d.tsType window.slashedApp pluginSettings for configurator_url +1/-0

Type window.slashedApp pluginSettings for configurator_url

• Extends the global Window typing to include 'pluginSettings.configurator_url', matching the embedded host boot payload used by 'getShareBaseUrl()'.

SLASHED-for-WP/admin-app/src/vite-env.d.ts

.vendored-manifest.jsonUpdate vendored manifest source metadata to local sync +54/-54

Update vendored manifest source metadata to local sync

• Updates vendoring metadata (source and sync timestamp) to reflect a local sync of framework configurator sources.

SLASHED-for-WP/admin-app/.vendored-manifest.json

app.cssRegenerate built CSS bundle +1/-1

Regenerate built CSS bundle

• Updates the compiled CSS output to reflect the header responsive/layout changes introduced in the source Svelte components.

SLASHED-for-WP/assets/admin-app/app.css

app.jsRegenerate built JS bundle for updated share/link and header UI behavior +25/-25

Regenerate built JS bundle for updated share/link and header UI behavior

• Updates the compiled JS artifact to include the new share URL generation logic (base override) and header responsiveness changes from Svelte source.

SLASHED-for-WP/assets/admin-app/app.js

@qodo-code-review

qodo-code-review Bot commented Jul 7, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (1) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 5 rules

Grey Divider


Remediation recommended

1. Silent share URL failures ✓ Resolved 🐞 Bug ☼ Reliability
Description
buildShareUrl() constructs new URL(baseUrl) and will throw for invalid/non-absolute
configurator_url values, but the updated share/copy handlers swallow all errors, so copying a
share link can fail with no feedback. This becomes likely once configurator_url is actually made
configurable (per the PR intent) because it currently has no strict server-side validation beyond
esc_url_raw.
Code

SLASHED-for-WP/admin-app/src/components/shell/StudioHeader.svelte[R36-42]

  async function handleShare() {
    try {
-      await navigator.clipboard.writeText(window.location.href);
+      const url = buildShareUrl(overrides, getShareBaseUrl());
+      await navigator.clipboard.writeText(url);
      shareFeedback = true;
      setTimeout(() => { shareFeedback = false; }, 2000);
    } catch {
Relevance

⭐⭐⭐ High

Team previously accepted adding explicit catch logging/feedback instead of silent failures in async
handlers (PR #90).

PR-#90

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The updated UI now passes a potentially configurable base URL into buildShareUrl, but
buildShareUrl uses the throwing URL constructor and both UI call sites intentionally ignore
exceptions, making failures invisible.

SLASHED-for-WP/admin-app/src/lib/codec.ts[278-285]
SLASHED-for-WP/admin-app/src/components/shell/StudioHeader.svelte[36-44]
SLASHED-for-WP/admin-app/src/components/panels/ExportPanel.svelte[25-32]
SLASHED-for-WP/includes/class-rest-controller.php[102-106]
SLASHED-for-WP/admin-app/src/lib/persistence.ts[198-201]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Share-link generation now depends on a configurable `configurator_url`, but URL parsing can throw (`new URL(...)`) and both share-copy call sites ignore exceptions. This produces a confusing UX where “Copy share link” does nothing if the configured base URL is malformed.

## Issue Context
- `buildShareUrl()` uses `new URL(baseUrl)`.
- `StudioHeader.handleShare()` and `ExportPanel.handleCopyLink()` wrap share building + clipboard write in `try/catch {}` and ignore errors.
- The REST arg for `configurator_url` is sanitized but not validated for being an absolute http(s) URL.

## Fix Focus Areas
- SLASHED-for-WP/admin-app/src/lib/codec.ts[278-285]
- SLASHED-for-WP/admin-app/src/lib/persistence.ts[198-201]
- SLASHED-for-WP/admin-app/src/components/shell/StudioHeader.svelte[36-45]
- SLASHED-for-WP/admin-app/src/components/panels/ExportPanel.svelte[25-32]
- SLASHED-for-WP/includes/class-rest-controller.php[102-106]

### Suggested approach
- Make `buildShareUrl` resilient to relative/invalid bases:
 - `const url = new URL(baseUrlOverride ?? fallbackUrl, fallbackUrl);` (or similar), wrapped in a small try/catch that falls back to `fallbackUrl`.
- Alternatively (or additionally), validate/normalize in `getShareBaseUrl()` (e.g. `try { return new URL(trimmed, window.location.href).toString(); } catch { return undefined; }`).
- Don’t swallow errors silently: at minimum log a warning, or set a UI flag so the user knows copying failed.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

2. Share base not configurable 🐞 Bug ≡ Correctness
Description
getShareBaseUrl() reads window.slashedApp.pluginSettings.configurator_url, but WordPress
bootstrapping always overwrites configurator_url with Slashed_Token_Page::CONFIGURATOR_URL, so
embedded hosts cannot supply a custom share base URL. As a result, share links will ignore the
saved/host-provided setting and always point at the hard-coded constant URL.
Code

SLASHED-for-WP/admin-app/src/lib/persistence.ts[R198-200]

+export function getShareBaseUrl(): string | undefined {
+  const url = wpBoot()?.pluginSettings?.configurator_url;
+  return url && url.trim() !== "" ? url : undefined;
Relevance

⭐ Low

Related configurator_url/constant bootstrapping concern was previously rejected by reviewers (PR
#36).

PR-#36

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The PR introduces getShareBaseUrl() that reads pluginSettings.configurator_url, but the
server-side boot payload always sets that key to a constant, overriding any persisted setting;
therefore the new configurability cannot work end-to-end.

SLASHED-for-WP/admin-app/src/lib/persistence.ts[189-201]
SLASHED-for-WP/includes/class-token-page.php[178-193]
SLASHED-for-WP/includes/class-rest-controller.php[102-106]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The frontend now relies on `window.slashedApp.pluginSettings.configurator_url` for share-link base URLs, but the WordPress boot payload forces `configurator_url` to a constant by merging it in *after* `$plugin_settings`. This makes the new “custom share URL base” feature non-functional.

## Issue Context
- `getShareBaseUrl()` reads `pluginSettings.configurator_url`.
- The WP boot payload currently sets `pluginSettings` via `array_merge(..., $plugin_settings, ...)` where the last merge wins, overwriting any user/host value.

## Fix Focus Areas
- SLASHED-for-WP/includes/class-token-page.php[178-193]
- SLASHED-for-WP/admin-app/src/lib/persistence.ts[198-201]

### Suggested approach
- In `wp_localize_script(...)`, set a default only once, e.g.:
 - `array_merge(['configurator_url' => self::CONFIGURATOR_URL], $plugin_settings)`
 - and remove the trailing `array('configurator_url' => self::CONFIGURATOR_URL)` that overwrites the setting.
- If you still need a “computed” URL that must not be overridden, store it under a different key (e.g. `default_configurator_url`) and have `getShareBaseUrl()` prefer the user setting when present.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Vendored files modified 📘 Rule violation § Compliance
Description
The PR modifies files that are explicitly listed as vendored in
SLASHED-for-WP/admin-app/.vendored-manifest.json (e.g., src/App.svelte and
src/lib/persistence.ts). This violates the rule that files listed in the vendored manifest must
not be edited in this repo’s change set.
Code

SLASHED-for-WP/admin-app/src/lib/persistence.ts[R198-201]

+export function getShareBaseUrl(): string | undefined {
+  const url = wpBoot()?.pluginSettings?.configurator_url;
+  return url && url.trim() !== "" ? url : undefined;
+}
Relevance

⭐ Low

Similar “vendored-file policy violation” was raised but PR merged without clear
enforcement/resolution (PR #125).

PR-#125

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The vendored manifest lists src/App.svelte and src/lib/persistence.ts as vendored files, but
this PR modifies those files (e.g., adds getShareBaseUrl() and passes {overrides} to
StudioHeader). Per the rule, any change to a path listed in the vendored manifest constitutes a
violation.

Rule 1514148: Do not modify vendored files listed in .vendored-manifest.json
SLASHED-for-WP/admin-app/.vendored-manifest.json[14-17]
SLASHED-for-WP/admin-app/.vendored-manifest.json[182-185]
SLASHED-for-WP/admin-app/src/App.svelte[276-279]
SLASHED-for-WP/admin-app/src/lib/persistence.ts[189-201]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Files listed in `SLASHED-for-WP/admin-app/.vendored-manifest.json` are being modified in this PR (vendored files must not be changed in this repository’s PR diff).

## Issue Context
The vendored manifest explicitly enumerates vendored paths (e.g., `src/App.svelte`, `src/lib/persistence.ts`). This PR changes those files (e.g., adds `getShareBaseUrl()` and passes `overrides` into `StudioHeader`).

## Fix Focus Areas
- SLASHED-for-WP/admin-app/src/lib/persistence.ts[198-201]
- SLASHED-for-WP/admin-app/src/App.svelte[276-279]
- SLASHED-for-WP/admin-app/.vendored-manifest.json[14-17]
- SLASHED-for-WP/admin-app/.vendored-manifest.json[182-185]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread SLASHED-for-WP/admin-app/src/components/shell/StudioHeader.svelte
Pulls in codeslash-dev/SLASHED@d96eba6: getShareBaseUrl() now validates
the host-provided configurator_url (must parse as an absolute http(s)
URL) before returning it, so a malformed value can't make "Copy link"
silently fail and a non-http(s) scheme can't be copied as a share link.
Falls back to the current page URL otherwise.

Addresses review feedback on #174.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QTPpAk2ynC74tuUAsVpYNf
@jackgranatowski
jackgranatowski merged commit c4ce6cf into main Jul 7, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants