Bug description
In a headless multisite setup, the CMS and public frontend run on different hosts.
Entry permalinks and SEO metadata are generated for the frontend host. For language/site root URLs (e.g. /, /fr), those URLs often include a trailing slash (https://www.example.com/fr/).
We expect Statamic’s default trailing-slash policy (no trailing slash unless URL::enforceTrailingSlashes() is enabled) to apply to those URLs as well.
What actually happens: URL::tidy() leaves them unchanged. Root URLs keep their trailing slash in canonical URLs, hreflang alternates, sitemap entries, etc.
Example:
| Field |
Value |
home_url |
https://www.example.com/fr ✅ |
canonical_url / permalink |
https://www.example.com/fr/ ❌ |
home_url is correct because it comes from Site::absoluteUrl(), which resolves site config properly. Entry permalinks go through URL::tidy() without normalization.
How to reproduce
Setup
- Configure split hosts:
APP_URL=https://cms.example.com
FRONTEND_URL=https://www.example.com
- In
resources/sites.yaml:
de:
url: '{{ config.app.frontend_url }}'
fr:
url: '{{ config.app.frontend_url }}/fr'
- Create/publish homepage entries for
de and fr (URI / on each site).
Steps
- Open Tinker or a test route on the CMS.
- Resolve a frontend root URL, e.g. the FR homepage permalink:
use Statamic\Facades\Entry;
use Statamic\Facades\URL;
$entry = Entry::query()->where('site', 'fr')->where('uri', '/')->first();
$permalink = $entry->absoluteUrl(); // e.g. https://www.example.com/fr/
- Compare tidy behavior:
URL::tidy($permalink); // https://www.example.com/fr/ ← trailing slash kept
URL::tidy($permalink, true); // https://www.example.com/fr ← normalized
Logs
Environment
Environment
Laravel Version: 12.66.0
PHP Version: 8.5.6
Composer Version: 2.10.0
Environment: local
Debug Mode: ENABLED
Maintenance Mode: OFF
Timezone: UTC
Locale: de
Statamic
Addons: 7
License Key: Set
Sites: 3 (🇩🇪 Deutsch, 🇫🇷 Français, 🇬🇧 English)
Stache Watcher: Enabled (auto)
Static Caching: Disabled
Version: 6.27.1 PRO
Statamic Addons
statamic/seo-pro: 7.13.1
Installation
Other (please explain)
Additional details
No response
Bug description
In a headless multisite setup, the CMS and public frontend run on different hosts.
Entry permalinks and SEO metadata are generated for the frontend host. For language/site root URLs (e.g.
/,/fr), those URLs often include a trailing slash (https://www.example.com/fr/).We expect Statamic’s default trailing-slash policy (no trailing slash unless
URL::enforceTrailingSlashes()is enabled) to apply to those URLs as well.What actually happens:
URL::tidy()leaves them unchanged. Root URLs keep their trailing slash in canonical URLs, hreflang alternates, sitemap entries, etc.Example:
home_urlhttps://www.example.com/fr✅canonical_url/permalinkhttps://www.example.com/fr/❌home_urlis correct because it comes fromSite::absoluteUrl(), which resolves site config properly. Entry permalinks go throughURL::tidy()without normalization.How to reproduce
Setup
resources/sites.yaml:deandfr(URI/on each site).Steps
Logs
Environment
Installation
Other (please explain)
Additional details
No response