<p>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.</p>

<pre><code>use craft\events\ElementEvent;
use craft\services\Elements;

Event::on(
    Elements::class,
    Elements::EVENT_AFTER_SAVE_ELEMENT,
    function (ElementEvent $event){
        //identify the right Entry for example test sectionId, typeId, authorId
        if ($event-&gt;element instanceof craft\elements\Entry) {  
            $entry = $event-&gt;element;
            //only newly created 
            if($event-&gt;isNew){                  
                $entry-&gt;slug = $entry-&gt;uid;
                Craft::$app-&gt;elements-&gt;saveElement($entry);                 
            }
        }
    }
);
</code></pre>

CC BY-SA 4.0
2018-10-08T12:06:49.593Z
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
CC BY-SA 4.0
2018-10-05T23:07:21.270Z
2018-10-05T23:07:21.270Z
lenka
<p>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?</p>

<p>If you use the entry's slug in the URI (<code>section-name/{slug}</code>), 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.</p>

<p>It's an old post and may be outdated, but I read <a href="https://craftcms.stackexchange.com/a/4949/960">here</a> that Craft doesn't expose the UID of an element so maybe that's part of the issue.</p>

CC BY-SA 4.0
2018-10-05T14:09:40.063Z
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
CC BY-SA 4.0
2018-10-05T14:13:00.847Z
Alright, that makes sense. Maybe add that to your question to make it more clear :)
Tom De Smet
CC BY-SA 4.0
2018-10-05T13:42:03.480Z
2018-10-05T13:47:39.473Z
2018-10-05T13:47:39.473Z
Tom De Smet
<p>I know this is a bit old, but I wanted to do the same and simply updated the <code>Entry</code> right after its original save.</p>
<p>Adding a basic version of my code below, with variables changed to underscores for readability only.</p>
<p>Hope it helps others. Of course, you'll need to validate and check for errors, etc.</p>
<pre><code>//get section
$sectionService = Craft::$app-&gt;getSections();
$section = $sectionService-&gt;getSectionByHandle($your_section_int);

//original Entry save
$entry = new Entry([
    'sectionId' =&gt; $section-&gt;id,
    'authorId' =&gt; $some_user_id,
    'typeId' =&gt; $section-&gt;getEntryTypes()[0]-&gt;id,
    'title' =&gt; $some_title_var,
]);
$entry-&gt;setFieldValue('customFieldName', $custom_field_val_1);
$entry-&gt;setFieldValue('anotherFieldName', $custom_field_val_2);
Craft::$app-&gt;getElements()-&gt;saveElement($entry);

//update Entry with UID as slug
$update = Craft::$app-&gt;entries-&gt;getEntryById($entry-&gt;id);
$update-&gt;slug = $update-&gt;uid;
Craft::$app-&gt;getElements()-&gt;saveElement($update);  
</code></pre>

CC BY-SA 4.0
2024-02-25T01:30:11.360Z
2024-02-25T01:30:11.360Z
Dario Zadro
<p>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.</p>

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

<p>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.</p>

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

<p>Is there a way to prevent this issue from happening?</p>

<p>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.</p>

<p>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.</p>

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

<url><modules>
How can I use the entry UID in the entry URI
# How can I use the entry UID in the entry URI

(Asked by: username_0 on 2018-10-05)

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?

**Tags:** url, modules


---

## 3 answers

### Answer by username_1 on 2018-10-05. Score: 2 | Accepted answer

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;

Event::on(
    Elements::class,
    Elements::EVENT_AFTER_SAVE_ELEMENT,
    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 
            if($event->isNew){                  
                $entry->slug = $entry->uid;
                Craft::$app->elements->saveElement($entry);                 
            }
        }
    }
);

> **Comments:**
> **username_0**: 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.  

---

### Answer by username_2 on 2018-10-05. Score: 1

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](https://craftcms.stackexchange.com/a/4949/960) that Craft doesn't expose the UID of an element so maybe that's part of the issue.

> **Comments:**
> **username_0**: 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.  
> **username_2**: Alright, that makes sense. Maybe add that to your question to make it more clear :)  

---

### Answer by username_3 on 2024-02-25. Score: 0

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);
Craft::$app->getElements()->saveElement($entry);

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


---

