Skip to content

fix(field): use the content type's record route in the snippet preview - #64

Merged
Fredxd merged 1 commit into
AppoloDev:mainfrom
Vondry:fix/snippet-preview-record-route
Oct 23, 2026
Merged

Fredxd merged 1 commit into
AppoloDev:mainfrom
Vondry:fix/snippet-preview-record-route

Conversation

@Vondry

@Vondry Vondry commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #18

Summary

#18 reports that the extension doesn't work for content types with a custom record_route (e.g. record_route: content_seo).

The frontend part is already fixed on main. Seo no longer switches on the record route name. Any route that exposes a record resolves the title, description and other values from the record's SEO field, and override_default can be keyed by the custom route name. I verified this with a custom content_seo route.

What remained is the Google snippet preview in the editor. Its URL was always built from the built-in record route:

absolute_url(path('record', { 'contentTypeSlug': ..., 'slugOrId': 'REPLACE' }))

so the preview showed a URL the page isn't served at when the content type:

  • uses a custom record_route, or
  • is localized and is being edited in a non-default locale (the preview always showed the default-locale URL).

Change

The preview URL is now built with Bolt's canonical() Twig function from the content type's record_route and the locale being edited (currentlocale). Bolt generates record links the same way (ContentHelper::getLink()). canonical() also:

  • drops contentTypeSlug when a custom route doesn't need it (no stray ?contentTypeSlug=…),
  • strips the default locale per localization.remove_default_locale_on_canonical,
  • uses the configured general/canonical host, matching the URL on the live page.

Backwards compatibility

This is a template-only change, with no PHP or config changes. For content types using the default record / record_locale routes, the preview URL is the same as before when editing the default locale. Because the preview now uses the configured general/canonical host instead of the backend request's host, it shows the public URL even when the admin is reached through a different hostname.

Manual verification (Bolt 6.1.9)

I tested this end-to-end on a fresh bolt/project install with the demo fixtures, plus three setups: pages (default record route), entries made localized (en, nl, so record_locale), and products with record_route: product_seo mapped to /shop/{slugOrId}. For each record, I took the snippet preview URL from the real edit page, substituted the slug the way seo.js does, and fetched that URL on the frontend.

Case Preview before Preview after Page's <link rel="canonical">
pages (record) /page/this-is-a-page /page/this-is-a-page /page/this-is-a-page
entries (record_locale), editing en /entry/… /entry/… /entry/…
entries (record_locale), editing nl /entry/… ❌ /nl/entry/… /nl/entry/…
products (custom product_seo) /product/… ❌ /shop/… /shop/…

After the change, every preview URL returns HTTP 200 and is identical to the page's canonical URL.

With remove_default_locale_on_canonical: false, Bolt itself renders the canonical of a non-localized record as …/page/this-is-a-page?_locale=en, because ContentHelper always passes _locale. The preview now shows that same URL, which is the one search engines are told to index. Before, it showed the bare /page/this-is-a-page.

Tests

New tests/Twig/SeoFieldTemplateTest.php renders the snippet preview block through a real Twig environment, with Bolt's functions stubbed:

  • testSnippetUrlUsesTheContentTypeRecordRoute: a custom record_route is used.
  • testSnippetUrlUsesTheEditedLocale: the edited locale is passed.

Both fail without the change. The suite passes (114 tests), and PHPStan is clean.

The Google snippet preview in the editor always built its URL from the
built-in `record` route. For a content type with a custom `record_route`,
or a localized record edited in a non-default locale, the preview showed
a URL the page is not served at.

Build it with Bolt's canonical() Twig function from the content type's
`record_route` and the edited locale, the same way Bolt generates record
links. canonical() also drops parameters the route doesn't need and the
default locale (per `remove_default_locale_on_canonical`), so the preview
is unchanged for content types using the default routes.

Refs AppoloDev#18
@Fredxd
Fredxd merged commit 4cb6693 into AppoloDev:main Oct 23, 2026
21 checks passed
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.

Support custom Record route names

2 participants