13

When updating from TYPO3 8.7 to TYPO3 9.5 you might drop the realurl extension in favor for the new routing feature.

But you might notice, that realurl appended a / to all urls by default (when you are not using html suffix) The TYPO3 routing feature does not do that by default and there is currently no option in the core to enable this. Why is this a problem? In TYPO3 8.7 you got an URL like www.domain.tld/subpage/. In TYPO3 9.5 the same page be called with the url www.domain.tld/subpage. So even if this is the same page, for search crawlers, this is another URL. TYPO3 does a 307 redirect when calling the URL with an appending /, but you might want to use your old URL structure.

How can I configure TYPO3 to add a trailing "/"?

Michael
  • 2,309
  • 1
  • 23
  • 34
Tim Schreiner
  • 513
  • 4
  • 14

4 Answers4

19

You can use the PageTypeEnhancer for mapping &type parameter in your site configuration (config.yaml file):

routeEnhancers:
  PageTypeSuffix:
    type: PageType
    default: '/'
    index: ''
    map:
      '/': 0
Tim Schreiner
  • 513
  • 4
  • 14
Ben
  • 811
  • 12
  • 28
  • 2
    Thanks, I've tested this and it seems to work with TYPO3 9.5.5 and is therefore a better solution. In earlier versions, you ended up with a double / for the homepage when using the pageType enhancer. Please also see my edit to not end up with /index/ for you rootpage. – Tim Schreiner Apr 20 '19 at 08:04
  • Does anyone using this solution where page-browser is also configured? – jokumer Aug 14 '20 at 09:10
  • Yes, f.e. with the news module like on https://stackoverflow.com/questions/54420293/good-practice-on-how-to-set-up-routeenhancers-for-list-and-detail-view-of-extne – Ben Aug 14 '20 at 13:03
  • Perfect, searching for this a while … working with TYPO3 10.4.6 also – MonTea Sep 01 '20 at 18:14
  • `index: ''` is not technically needed here – User366 Jan 27 '21 at 13:26
  • @User366 without `index: ''` the homepage would be www.domain.com/index/ instead of just www.domain.com – Ben Jan 27 '21 at 13:41
9

To always add an appending /, you can create yourself a route enhancer decorator and put it in your site package.

Create a file in your site package under Classes/Routing/Enhancer/ForceAppendingSlashDecorator.php with the content:

<?php
declare(strict_types=1);
namespace MyVendor\SitePackage\Routing\Enhancer;

use TYPO3\CMS\Core\Routing\Enhancer\AbstractEnhancer;
use TYPO3\CMS\Core\Routing\Enhancer\DecoratingEnhancerInterface;
use TYPO3\CMS\Core\Routing\RouteCollection;

class ForceAppendingSlashDecorator extends AbstractEnhancer implements DecoratingEnhancerInterface
{
    /**
     * {@inheritdoc}
     */
    public function getRoutePathRedecorationPattern(): string
    {
        return '\/$';
    }

    /**
     * {@inheritdoc}
     */
    public function decorateForMatching(RouteCollection $collection, string $routePath): void
    {
        foreach ($collection->all() as $route) {
            $route->setOption('_decoratedRoutePath', '/' . trim($routePath, '/'));
        }
    }

    /**
     * {@inheritdoc}
     */
    public function decorateForGeneration(RouteCollection $collection, array $parameters): void
    {
        foreach ($collection->all() as $routeName => $existingRoute) {
            $existingRoutePath = rtrim($existingRoute->getPath(), '/');
            $existingRoute->setPath($existingRoutePath . '/');
        }
    }
}

Please replace set the correct namespace matching your site package.

To register your route enhancer, add the line to your ext_localconf.php:

$GLOBALS['TYPO3_CONF_VARS']['SYS']['routing']['enhancers']['ForceAppendingSlash'] = \MyVendor\SitePackage\Routing\Enhancer\ForceAppendingSlashDecorator::class;

As a last step, put the following code into your site configuration yaml file:

routeEnhancers:
  PageTypeSuffix:
    type: ForceAppendingSlash

After this adjustments, TYPO3 will always add an appending / to your URLs so the new URLs will match the old ones created by realurl.

Tim Schreiner
  • 513
  • 4
  • 14
3

Additional to the answer from Tim Schreiner, i made a condition in the .htaccess file, which redirects urls whithout slashes to the url with trailing slash. Files should not be affected by this condition. Following condition did i add to the .htaccess file:

# EXTRA: Enforce trailing slash. Ignore trailing slash on file endings 
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteCond %{REQUEST_FILENAME} !\.(gif|jpg|png|jpeg|css|js|xml|rss|txt)$ [NC]
RewriteCond %{REQUEST_URI} !\.(gif|jpg|png|jpeg|css|js|xml|rss|txt)$ [NC]
RewriteRule ^(.*[^/])$ /$1/ [L,R=301]
kimomat
  • 2,211
  • 23
  • 37
  • 2
    This is a 301 redirect which is better than a 302. But not as good as being able to generate the link with the trailing / in the first place. An unnececcary redirect is evil. Imho that really needs to be configurable in TYPO3 itself. – Hafenkranich Mar 07 '19 at 17:35
  • also if you do that redirect make sure your non default languages site config does correspond to your trailing slash choice! Otherwise you might run in an endless redirect loop. – Hafenkranich Mar 07 '19 at 17:37
  • Also, this solution only works for Apache Webserver. If you have nginx or something else delivering the site, you would need another solution. So I totally agree this should be configurable in the core instead to prevent workarounds like this one. – Michael Apr 03 '19 at 06:45
0

Tim, are you sure about getRoutePathRedecorationPattern()?

For me, it worked in two totally different TYPO3 (v9.5.3) instances in production, but both projects did not work in a ddev-container. There, the slugCandidates have always missed its last char.

Changing the pattern from "all except slash" to "exactly a slash" makes it work.

public function getRoutePathRedecorationPattern(): string
{
    return '\/$';
}
Julian Hofmann
  • 2,081
  • 1
  • 8
  • 16
  • 2
    I recommend to move the question to a less prominent position. Try to turn this into a more assertive answer. Maybe write a comment on your own answer (you **can**, you know) to discuss with Tim. – Yunnosch Jan 11 '19 at 13:24
  • 1
    I can approve this. I recently updated from 9.5.1 to 9.5.4 and my site broke. I 9.5.1, my displayed solution worked for me. I 9.5.4, it broke the site. Changing it to your solution worked for me, too. – Tim Schreiner Jan 23 '19 at 13:29