The entries in my Craft app need a unique ‘non-guessable’ URL, so I figured I could use the UID in the URI of the entry.

So in the section, where I need to provide the URI format I entered "section-name/{uid}".

But this is giving me issues, since when I initially save an entry, the URI is "section-name". I think this is because the UID is not available on creation of the URI.

If I save the element for the second time, my problem is solved and the correct URI is generated.

Is there a way to prevent this issue from happening?

I already thought about creating a route, but that means that I need to generate the URI myself in every template, and this is prone to error and not future proof if we would like to change the URI format.

I also thought about creating a module which saves the entry for a second time when a new entry is saved for that section, but I can't find a way to create the correct event-listener.

Does anyone have a better solution or can help me with the event listener in a module?

3 Answers 3


I think this can be a starting solution. It rewrite slug of Entry after the Entry is saved to database. The URI is constructed from it. You can try it in any plugin, only register the EVENT_AFTER_SAVE_ELEMENT in init() function of Plugin.

use craft\events\ElementEvent;
use craft\services\Elements;

    function (ElementEvent $event){
        //identify the right Entry for example test sectionId, typeId, authorId
        if ($event->element instanceof craft\elements\Entry) {  
            $entry = $event->element;
            //only newly created 
                $entry->slug = $entry->uid;
  • Thanks, that is exactly what I was looking for. Since I set the URI to /{slug} in the section settings, I did not need to rewrite the slug. So the line $entry->slug = $entry->uid; can be deleted. It was added automatically after saving the second time. I guess because now it has the UID available, and on creation it hasn't.
    – Dries
    Commented Oct 8, 2018 at 12:06

I may be missing something here, but is the URL of an entry not always unique? How would Craft else know what entry to show?

If you use the entry's slug in the URI (section-name/{slug}), wouldn't that do the trick? A slug is unique within a section and every section has a unique name, so the URL would be unique too. And {slug} is defenitely known in the URI.

It's an old post and may be outdated, but I read here that Craft doesn't expose the UID of an element so maybe that's part of the issue.

  • Thx for your answer Tom. The entries should have a ‘non-guessable’ url. So a uid is ideal. In the current version the uid is exposed. And my idea is working if i save an entry for the secobd time. Probably because a uid is available in the DB by then.
    – Dries
    Commented Oct 5, 2018 at 14:09
  • Alright, that makes sense. Maybe add that to your question to make it more clear :) Commented Oct 5, 2018 at 14:13

I know this is a bit old, but I wanted to do the same and simply updated the Entry right after its original save.

Adding a basic version of my code below, with variables changed to underscores for readability only.

Hope it helps others. Of course, you'll need to validate and check for errors, etc.

//get section
$sectionService = Craft::$app->getSections();
$section = $sectionService->getSectionByHandle($your_section_int);

//original Entry save
$entry = new Entry([
    'sectionId' => $section->id,
    'authorId' => $some_user_id,
    'typeId' => $section->getEntryTypes()[0]->id,
    'title' => $some_title_var,
$entry->setFieldValue('customFieldName', $custom_field_val_1);
$entry->setFieldValue('anotherFieldName', $custom_field_val_2);

//update Entry with UID as slug
$update = Craft::$app->entries->getEntryById($entry->id);
$update->slug = $update->uid;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.