Skip to content

Document URLs: Retrieve only the current culture's URL for the Info workspace links panel (closes #23196) - #23265

Merged
AndyButland merged 11 commits into
v17/devfrom
v17/improvement/23196-optimise-document-url-retrieval
Jul 14, 2026
Merged

Document URLs: Retrieve only the current culture's URL for the Info workspace links panel (closes #23196)#23265
AndyButland merged 11 commits into
v17/devfrom
v17/improvement/23196-optimise-document-url-retrieval

Conversation

@AndyButland

@AndyButland AndyButland commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Description

When editing content in the backoffice, the Info workspace view's "Links" panel calls GET /umbraco/management/api/v1/document/urls. For each document this resolves the URL for every installed culture and, to detect naming collisions, routes each generated URL back through the full content-finder pipeline (PublishedUrlInfoProvider.GetAllAsyncVerifyCollisionAsyncIPublishedRouter.RouteRequestAsync).

On a site with many languages and custom, expensive IContentFinders, this is costly: a reporter with a 24-language setup and slow finders sees the finder chain run 24 times just to render the links for one document — even though the panel only ever displays the culture currently being viewed (the client already filtered the all-cultures response down to the current culture for variant documents).

To mitigate this, I've amended the behaviour to request and resolve only the culture being displayed for variant documents, turning N finder routes into 1 per panel load.

Fixes #23196.

Server

  • IPublishedUrlInfoProvider.GetAllAsync gains an optional culture overload (added as a default interface method for binary compatibility). PublishedUrlInfoProvider scopes the lookup to the requested culture when it is a valid installed culture, and ignoring culture for invariant content.
  • IDocumentUrlFactory gains culture-aware overloads (default interface methods).
  • DocumentUrlController GET .../document/urls gains an optional ?culture= query parameter.
  • OpenApi.json and the generated TypeScript client updated to include the new optional parameter.

Client

  • The Info "Links" panel requests only the currently displayed culture for variant documents (omitting culture for invariant documents, which still list all domain URLs).
  • The URLs data resolver now tracks the displayed culture reactively and exposes it, so switching the editor language re-fetches that culture's URL.

Performance Considerations

This PR is primarily to support setups that have many languages, on the basis that given the URLs are viewed one by one, it makes sense to not have to wait to retrieve them all.

There is a downside in that now on switching language, there will be a request to get the URL for that language. We are no longer getting them all up front. On balance this feels right - it's likely not a very common editor interaction to repeatedly switch between languages in quick succession, and the request is now small and much faster. I've improved the loading indication so there's no longer a flicker of "This document is published but not in the cache". I did consider a cache - so once a URL is retrieved it's not got again unless it's necessary - but it seemed like a lot of moving parts and a staleness risk for little benefit.

Testing

Automated

Unit tests on server and client, and integration tests on the server, have been added/updated to verify the functionality.

Manual

  1. Create a culture-variant document type and add several languages, each with its own domain assigned.
  2. Open a variant document and go to the Info workspace view. Observe a single request GET .../document/urls?id=<key>&culture=<current-culture>.
  3. Switch the editor to another language — a new request is made for that culture only, and the correct URL is shown.
  4. Open an invariant document's Info view — all of its domain URLs are still listed (behaviour unchanged).
  5. Publish while on the Info view — the links refresh for the current culture.

Copilot AI review requested due to automatic review settings July 2, 2026 04:22
@claude

claude Bot commented Jul 2, 2026

Copy link
Copy Markdown

Claude finished @AndyButland's task in 7m 1s —— View job


PR Review

Target: origin/v17/dev · Based on commit: 0d6a54b1 · Skipped: 1 file out of 15 total (types.gen.ts)

Scopes the GET /document/urls endpoint to a single culture for variant documents, turning the N-finder-routes-per-culture problem into a 1-route-per-panel-load fix. All layers (Core interface, implementation, Management API controller + factory, TypeScript client, tests) are updated consistently.

  • Modified public API: IPublishedUrlInfoProvider.GetAllAsync (new overload), IDocumentUrlFactory.CreateUrlsAsync / CreateUrlSetsAsync (new overloads), DocumentUrlController.GetUrls (obsoleted action + new action with optional culture param)
  • Affected implementations (outside this PR): External implementations of IPublishedUrlInfoProvider and IDocumentUrlFactory — covered by the new default interface methods which delegate to the existing parameterless overloads.

Note

Complexity advisory — This PR may benefit from splitting.

  • Layer spread: 4 layers touched (Core, API.Management, Frontend, Tests) across 14 reviewable files. That said, the change is a single coherent optimization that must land atomically across all layers — splitting by layer would ship a half-broken feature. This is noted for awareness, not as an actionable concern.

This is an observation, not a blocker. The full review follows below.


Suggestions

  • src/Umbraco.Cms.Api.Management/Factories/IDocumentUrlFactory.cs:25: Missing // TODO (V19): Remove the default implementation. comment — sibling interfaces (IDocumentEditingPresentationFactory, IMemberPresentationFactory) consistently annotate default interface methods with this. Same applies to line 41 on the same file.
  • src/Umbraco.Core/Routing/IPublishedUrlInfoProvider.cs:24: Same missing TODO comment.
  • src/Umbraco.Web.UI.Client/src/packages/documents/documents/url/repository/document-url.repository.ts:10: #urlSource is a second UmbDocumentUrlServerDataSource instance alongside the one already created by UmbItemRepositoryBase. Not a bug (the comment explains the rationale), but overriding requestItems to thread culture? through could avoid the duplicate. Not a blocker.

Approved with Suggestions for improvement

Good to go. The optimization is well-targeted, the breaking-change mitigations correctly follow the established patterns, and the test coverage addresses all the key cases (invariant, variant, unknown culture). The suggestions above are minor polish items.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR optimizes the Management API + backoffice “Info → Links” panel flow by allowing URL resolution to be scoped to the currently displayed culture for variant content, avoiding unnecessary per-culture routing/content-finder execution while keeping collision detection behavior intact.

Changes:

  • Added culture-aware overloads for document URL resolution (IPublishedUrlInfoProvider, IDocumentUrlFactory) and implemented server-side culture scoping in PublishedUrlInfoProvider.
  • Extended GET /umbraco/management/api/v1/document/urls with optional ?culture= and updated OpenAPI + generated TS client types accordingly.
  • Updated backoffice URLs fetching to request only the displayed culture for variant documents (and to re-fetch on culture switch), with unit/integration/client tests covering the new behavior.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/Umbraco.Tests.UnitTests/Umbraco.Cms.Api.Management/Factories/DocumentUrlFactoryTests.cs Adds unit coverage ensuring the factory passes culture through and that parameterless overloads delegate as “all cultures”.
tests/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/UrlAndDomains/DomainAndUrlsTests.cs Adds integration coverage for culture-scoped URL results and unknown-culture fallback behavior.
tests/Umbraco.Tests.Integration/Umbraco.Core/Services/PublishedUrlInfoProviderTests.cs Adds integration coverage that invariant content ignores requested culture.
src/Umbraco.Web.UI.Client/src/packages/documents/documents/url/repository/document-url.server.data-source.ts Adds optional culture to the client request so the server can scope URL resolution.
src/Umbraco.Web.UI.Client/src/packages/documents/documents/url/repository/document-url.server.data-source.test.ts Verifies culture is included/omitted in the query string as expected.
src/Umbraco.Web.UI.Client/src/packages/documents/documents/url/repository/document-url.repository.ts Introduces a culture-aware requestUrls() path that still populates the URL store.
src/Umbraco.Web.UI.Client/src/packages/documents/documents/url/info-app/document-links-workspace-info-app.element.ts Requests URLs using the displayed culture for variant documents and re-requests on culture switch (debounced).
src/Umbraco.Web.UI.Client/src/packages/documents/documents/url/document-urls-data-resolver.ts Tracks displayed culture reactively and exposes it as requestCulture + getRequestCulture().
src/Umbraco.Web.UI.Client/src/packages/core/backend-api/types.gen.ts Updates generated client types to include the optional culture query parameter.
src/Umbraco.Core/Routing/PublishedUrlInfoProvider.cs Implements culture-scoped URL resolution for variant content and filters “other URLs” accordingly.
src/Umbraco.Core/Routing/IPublishedUrlInfoProvider.cs Adds default-interface-method overload supporting optional culture scoping (non-breaking).
src/Umbraco.Cms.Api.Management/OpenApi.json Adds the optional culture query parameter to the document URLs endpoint contract.
src/Umbraco.Cms.Api.Management/Factories/IDocumentUrlFactory.cs Adds culture-aware overloads via default interface methods.
src/Umbraco.Cms.Api.Management/Factories/DocumentUrlFactory.cs Wires the optional culture through to IPublishedUrlInfoProvider.
src/Umbraco.Cms.Api.Management/Controllers/Document/DocumentUrlController.cs Adds the optional culture query param endpoint overload and delegates from the obsolete signature.

Comment thread src/Umbraco.Cms.Api.Management/Factories/IDocumentUrlFactory.cs
Comment thread src/Umbraco.Cms.Api.Management/Factories/IDocumentUrlFactory.cs
Comment thread src/Umbraco.Core/Routing/IPublishedUrlInfoProvider.cs
@claude claude Bot added area/backend area/frontend category/api category/performance Fixes for performance (generally cpu or memory) fixes labels Jul 2, 2026
@andr317c

Copy link
Copy Markdown
Contributor

I just tested this PR and it looks good 💪, I followed the manual steps and I also checked the info tabs in split view which also worked with getting both of the selected culture urls

@sonarqubecloud

Copy link
Copy Markdown

@iOvergaard iOvergaard left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

Pulled it down, merged v17/dev in (clean), and verified: regenerated OpenApi.json and the client types both diff to zero against yours, so the whole chain's in sync. Browser-tested too — Info panel requests only the displayed culture (?culture=en-US, then ?culture=da on switch), and no more "not in cache" flicker.

Mads's points look handled 👍

@AndyButland
AndyButland enabled auto-merge (squash) July 14, 2026 09:50
@AndyButland
AndyButland merged commit bc1f1ba into v17/dev Jul 14, 2026
33 checks passed
@AndyButland
AndyButland deleted the v17/improvement/23196-optimise-document-url-retrieval branch July 14, 2026 10:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants