Skip to content

GBK Plain Permalink Support #563

Description

@jkmassel

GutenbergKit's native REST URL builder assumes a path-based site API root, so it can't address a self-hosted WordPress site that uses plain permalinks — where the only REST root is the query form https://site/?rest_route=/.

Summary

  • WordPressRESTURL.namespaced (iOS) and RestUrlBuilder.namespaced (Android) build every native REST URL by appending the endpoint to the path (apiRoot.appending(path:) / string concat).
  • A plain-permalink site has no path-based REST root: /wp-json/ depends on the rewrite rules that plain permalinks disable, so WordPress advertises ?rest_route=/ as the site's REST root.
  • Result: for such a site, every native REST URL is malformed — not just media uploads.
  • WP.com sites are unaffected — they're reached through the path-based public-api.wordpress.com/ proxy (SitePreparationView.swift / SitePreparationViewModel.kt set siteApiRoot = https://public-api.wordpress.com/), which abstracts the underlying site's permalinks away.

Root cause

namespaced does apiRoot.appending(path:). Given siteApiRoot = https://site/?rest_route=/:

namespaced(root, "/wp-block-editor/v1/settings") → https://site/wp-block-editor/v1/settings?rest_route=/   → 404
namespaced(root, "/wp/v2/media")                 → https://site/wp/v2/media?rest_route=/                   → 404

The /wp/v2/… lands on the URL path (which doesn't route on a plain-permalink site) with a stray rest_route=/ query, instead of https://site/?rest_route=/wp/v2/media.

Impact

Every endpoint routed through namespaced — in RESTAPIRepository alone: editor settings, active theme, site settings, post types — plus the native media-upload endpoint. namespaced has no rest_route handling and its unit tests (both platforms) cover only path-based roots.

This is pre-existing — the logic was extracted from the prior buildNamespacedURL and carried the assumption forward. It surfaced while reviewing the native media-upload work (#561), whose mediaEndpointURL relies on namespaced.

Proposed fix

Teach namespaced (both platforms) to detect a rest_route query on the root and append the endpoint — and the site namespace — to the rest_route value rather than the URL path:

root = https://site/?rest_route=/
build /wp/v2/media → https://site/?rest_route=/wp/v2/media   ✓

Path-based roots keep today's behavior. Add the query-based-root tests the builders never had. This fixes all native endpoints at once, and the media upload's ?_embed=wp:featuredmedia query then merges correctly for free (there's a latent iOS/Android divergence in mediaEndpointURL's query append — percentEncodedQuery overwrite vs + concat — that's moot until the base is correct).

Open question

Reachability depends on whether the host apps (WordPress-iOS / Jetpack) actually connect to self-hosted plain-permalink sites and hand GutenbergKit a ?rest_route= root. Worth confirming before prioritizing — though a plain-permalink site has nothing else it could hand over.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions