Skip to content

fix: build the editor assets endpoint for sites using plain permalinks - #25859

Open
dcalhoun wants to merge 8 commits into
trunkfrom
fix/editor-assets-endpoint-plain-permalinks
Open

fix: build the editor assets endpoint for sites using plain permalinks#25859
dcalhoun wants to merge 8 commits into
trunkfrom
fix/editor-assets-endpoint-plain-permalinks

Conversation

@dcalhoun

@dcalhoun dcalhoun commented Jul 31, 2026

Copy link
Copy Markdown
Member

Description

Note

Targets the fix/gutenbergkit-localization-fallback branch to inherit unmerged translation string changes to avoid build failures.

Ref wordpress-mobile/GutenbergKit#563. Fixes the editor assets endpoint for self-hosted sites that use plain permalinks.

Such a site has no path-based REST root — /wp-json/ depends on the rewrite rules that plain permalinks disable, so WordPress advertises the query form https://site/?rest_route=/. wordpress-rs discovers that value from the site's https://api.w.org/ Link header and it's stored verbatim in Blog.restApiRootURL, so it reaches EditorConfiguration as-is.

appendPathComponent appended the endpoint to the URL path, stranding the query:

https://site/?rest_route=/  ->  https://site/wpcom/v2/editor-assets?rest_route=/   ✗
                            ->  https://site/?rest_route=/wpcom/v2/editor-assets   ✓

The malformed URL doesn't 404. A trailing ?rest_route=/ routes to the REST API root and the path is ignored, so the request returns 200 with the API index — the wrong resource. Decoding it as an asset manifest then fails, and the editor doesn't open at all:

Editor Error
The data couldn't be read because it is missing.

So the symptom is a fatal editor failure for these sites, not merely missing blocks. The endpoint is built here in the host app and passed to GutenbergKit pre-built, so GutenbergKit can't fix it — see wordpress-mobile/GutenbergKit#573, which fixes the equivalent problem in GutenbergKit's own URL builders.

The fix concatenates onto the API root rather than appending path components, so a query-based root grows its rest_route value. Path-based and WP.com roots are unchanged. This matches how @wordpress/api-fetch's root URL middleware and GutenbergKit's native builders handle the same case, so all layers resolve identical endpoints.

Testing instructions

Requires a self-hosted site set to Settings ▸ Permalinks ▸ Plain, connected to Jetpack (third-party block assets are limited to Jetpack-connected sites1), and signed in with an application password.

Confirm the site advertises the query-form root first:

curl -sI https://your-site.com/ | grep -i '^link'

The rel="https://api.w.org/" value should contain ?rest_route=/ rather than /wp-json/.

  1. Sign in to that site and open a post in the experimental Gutenberg editor.
  2. Confirm the editor opens and the post's content renders.
  3. Confirm third-party blocks (e.g. Jetpack blocks) appear in the inserter and render correctly.

Before this change the editor failed to open on step 2, showing an "Editor Error" screen reading "The data couldn't be read because it is missing." — so step 3 was unreachable.

Also confirm no regression for a self-hosted site with pretty permalinks and for a WP.com site — both build the same endpoint as before.

Unit tests cover all three root shapes in EditorConfigurationTests.

Footnotes

  1. This is a legacy, overly broad limitation that no longer matches WordPress-Android. It should be updated to to match in a separate PR.

dcalhoun and others added 6 commits July 29, 2026 15:18
GutenbergKit#569 adds `EditorLocalizableString.patternsCount(Int)`, which is
source-breaking for hosts that switch over the enum exhaustively. Track the
PR build so the companion changes can land and be tested together.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
GutenbergKit#569 adds `patternsCount(Int)`, which previously rendered as a
hardcoded English string. Translate it, splitting singular and plural so
each reads naturally.

Also delegate unhandled keys to `EditorLocalization.defaultLocalize(_:)`.
The switch was exhaustive, so every string the editor added broke this build
until someone wrote a translation — and the break surfaced on the dependency
bump, not when the string was added. New keys now render in English until
translated.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A plain `default` warns "default will never be executed" because this switch
covers every case the pinned GutenbergKit defines. `@unknown default`
compiles clean and behaves the same once the editor adds a string.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
GutenbergKit#569 changed `EditorLocalization.localize` to return `String?`.
Hosts now decline a key by returning `nil` instead of calling a public
`defaultLocalize`, so the editor supplies the string and reports the gap.

`getLocalizedString(for:)` and `EditorLocalizableString.localized` return
`String?`, and the fallback case yields `nil`. The install site in
PostGBKEditorViewController needs no change: `{ $0.localized }` already
matches the new closure type.

Keeps the `@unknown default` from 88bbcf4. It stays reachable only for
keys a future GutenbergKit adds; every case defined today is still handled
explicitly, so the pattern count keeps its own translation rather than
falling through.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@dcalhoun
dcalhoun force-pushed the fix/editor-assets-endpoint-plain-permalinks branch from 0ecb5c3 to 0a7be6b Compare July 31, 2026 23:02
@dangermattic

Copy link
Copy Markdown
Collaborator
1 Message
📖 This PR is still a Draft: some checks will be skipped.

Generated by 🚫 Danger

@wpmobilebot

wpmobilebot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor
App Icon📲 You can test the changes from this Pull Request in WordPress by scanning the QR code below to install the corresponding build.
App NameWordPress
ConfigurationRelease-Alpha
Build Number33583
VersionPR #25859
Bundle IDorg.wordpress.alpha
Commit7c73874
Installation URL27uebpvhkpqno
Automatticians: You can use our internal self-serve MC tool to give yourself access to those builds if needed.

@wpmobilebot

wpmobilebot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor
App Icon📲 You can test the changes from this Pull Request in Jetpack by scanning the QR code below to install the corresponding build.
App NameJetpack
ConfigurationRelease-Alpha
Build Number33583
VersionPR #25859
Bundle IDcom.jetpack.alpha
Commit7c73874
Installation URL1a2ftlvubo5j8
Automatticians: You can use our internal self-serve MC tool to give yourself access to those builds if needed.

dcalhoun and others added 2 commits August 3, 2026 13:20
A site using plain permalinks has no path-based REST root — WordPress
advertises the query form `https://site/?rest_route=/` instead, and
that value is stored verbatim in `Blog.restApiRootURL` by wordpress-rs
Link-header discovery.

`appendPathComponent` appended the endpoint to the URL path, stranding
the query and producing
`https://site/wpcom/v2/editor-assets?rest_route=/`, so third-party block
assets never loaded for those sites.

Concatenate onto the API root instead, which grows the `rest_route`
value while leaving path-based and WP.com roots unchanged. This mirrors
`@wordpress/api-fetch` and GutenbergKit's native URL builders, so every
layer resolves the same endpoints for a given site.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@dcalhoun
dcalhoun force-pushed the fix/editor-assets-endpoint-plain-permalinks branch from 0a7be6b to 7c73874 Compare August 3, 2026 17:25
@dcalhoun
dcalhoun changed the base branch from trunk to fix/gutenbergkit-localization-fallback August 3, 2026 17:25
@dcalhoun
dcalhoun marked this pull request as ready for review August 3, 2026 17:41
@dcalhoun
dcalhoun requested a review from jkmassel August 3, 2026 17:41
Base automatically changed from fix/gutenbergkit-localization-fallback to trunk August 4, 2026 19:29
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.

3 participants