wordpress-mobile / wordpress-mobile/GutenbergKit

GBK Plain Permalink Support

Open
#563 1 comment 0 reactions 1 assignee View on GitHub

@dcalhoun is already working on this.

Since Jul 31, 2026.

Bug Gutenberg
Dominant language
JavaScript
Stars
29
Forks
6
Avg merge
1d 9h
Merged PRs (30d)
41

Description

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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.