You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
⚠️ **Breaking Change Notice**
This change introduces a breaking behavior adjustment in the GraphQL
`page` query to align its handling of **Vanity URLs** with the behavior
of the **REST Page API**.
### Background
On the REST `/api/v1/page/render/{uri}` endpoint:
- If the requested URL is associated with a **temporary** or **permanent
redirect**, the response contains:
- An **empty** `page` object, and
- A `vanityUrl` object describing the redirect (`forwardTo`, `action`,
etc.).
- If the Vanity URL is a **200 forward**, the response contains:
- The **resolved page** (i.e., the target of the forward), and
- The corresponding `vanityUrl` metadata.
### Previous Behavior in GraphQL (Inconsistent)
When querying a page using a Vanity URL (e.g., `page(url:
"/vanity-redirect")`), GraphQL would:
- Return the `page` object of the **original URI**, even for redirects.
- Also include the `vanityUrl` info.
- It did **not** respect the redirect semantics (301/302), nor return an
empty page as expected.
### New Behavior (Aligned with Page API)
After this update:
- For **temporary** or **permanent redirects**, GraphQL will return:
- An **empty** `page` object, and
- A `vanityUrl` object with proper redirect metadata.
- For **200 forwards**, GraphQL will return:
- The **resolved page content** (from the target of the forward), and
- The associated `vanityUrl`.
### Impact
Clients that rely on the GraphQL `page` query **will be affected** when
querying URIs that are referenced by Vanity URLs.
Specifically:
- If the URI is associated with a **temporary (302)** or **permanent
(301)** redirect:
- The `page` object will now be **empty**, and
- Only the `vanityUrl` metadata will be returned.
- If the URI is associated with a **forward (200)**:
- The returned `page` will represent the **resolved target page**, not
the original URI.
This change ensures GraphQL behaves consistently with the REST Page API,
but may require consumers to update their logic to properly handle
redirects or forwards based on `vanityUrl.action`.
---
### Proposed Changes
- **PageDataFetcher**
- Hook into the Vanity-URL API before rendering:
1. Resolve via `APILocator.getVanityUrlAPI().resolveVanityUrl(...)`
2. **Redirects**: return an “empty” `Contentlet` (so GraphQL can
serialize `vanityUrl` but no page data)
3. **Forwards**: rewrite the fetch URI and continue to render the target
page
- Store the resolved `CachedVanityUrl` in the GraphQL context so
downstream `VanityURLFetcher` can pick it up.
- **VanityURLFetcher**
- First check for a `cachedVanityUrl` in the GraphQL context and return
it directly if present, falling back to the normal lookup otherwise.
### Checklist
- [x] Tests
- [x] Translations
- [x] Security Implications Contemplated (add notes if applicable)
### Additional Info
- Matches the REST behavior in `/api/v1/page/render/{uri}`
- Verified manually in GraphQL Playground with three scenarios:
```graphql
query VanityTest {
forward: page(url: "/vanity-forward") { pageURI url vanityUrl {
forwardTo uri action } }
temporary: page(url: "/vanity-temporary-redirect") { pageURI url
vanityUrl { forwardTo uri action } }
permanent: page(url: "/vanity-permanent-redirect") { pageURI url
vanityUrl { forwardTo uri action } }
urlContentMapForward: page(url:
"/blog/post/french-polynesia-everything-you-need-to-know") { pageURI url
vanityUrl { forwardTo uri action } } }

0 commit comments