---
title: "Speaking URLs - Slugs"
version: "15.0"
source: "DeveloperManual/Features/SpeakingUrl.rst"
rendered: "2026-10-02T18:05:42+00:00"
---

# Speaking URLs - Slugs {#speaking-urls-slugs}

A slug is a unique name for an resource.
The index has an slug field for all indices and can be used to map a "speaking URL" segment to an index.
Since an event can produce multiple indices, we need an extra logic to generate unique slugs for them.

## Slug structure {#slug-structure}

The slug of an index consists out of multiple parts:

```php
{1:base-slug}-{2?:slug-suffix}-{3?:regular-core-conflict-counter}

```

1.  `base-slug`

    Speaking part of the slug for each event using the `SpeakingUrlInterface` (or a fallback method).
1.  `slug-suffix` (optional)

    Additionally date suffix for events with multiple occurrences.
1.  `regular-core-conflict-counter` (optional)

    Counting suffix to prevent duplicates, if the previous slug already exists.

## Custom base slug for own events {#custom-base-slug-for-own-events}

The `SpeakingUrlInterface` can be used to generate the base slug for events.
Implement this interface in your event model and return a value e.g. a title or slug.
Alternatively, you could name your slug field `slug` or `path_segment`.

## Extend the slug generation {#extend-the-slug-generation}

The slugs are generated inside `SlugService` and can be expanded by using the following PSR-14 events:

-   `BaseSlugGenerationEvent`
-   `SlugSuffixGenerationEvent`

### SlugSuffixGenerationEvent example {#slugsuffixgenerationevent-example}

This example shows how to add a custom suffix to the slug, in this case the start time of the event.
A resulting slug could look like `test-20201103-1715`.

```php
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\EventListener;

use HDNET\Calendarize\Event\SlugSuffixGenerationEvent;

final class AddEventTimeSlugListener
{
    public function __invoke(SlugSuffixGenerationEvent $event): void
    {
        // Optional: some additional checks, e.g. based on Model or page id (pid)
        // Get the start_time (seconds since day start) from the record
        $startTime = $event->getRecord()['start_time'];
        // Add to the existing slug (e.g. test-20201103) the current time (17:15)
        // resulting in test-20201103-1715
        $newSlug = $event->getSlug() . '-' . date('Hi', $startTime);
        // Update the slug
        $event->setSlug($newSlug);
    }
}
```

Then register the event in your extension's `Configuration/Services.yaml`:

```yaml
services:
  # ...
  MyVendor\MyExtension\EventListener\AddEventTimeSlugListener:
    tags:
      - name: event.listener
        identifier: 'addEventTimeSlug'
```

See [Using and dispatching events in extensions](https://docs.typo3.org/m/typo3/reference-coreapi/14.3/en-us/ExtensionArchitecture/HowTo/Events/Index.html#extension-development-events) for more details on implementing PSR-14 events.
