Solving Duplicate URL Slugs for Repeated Talks: A Future-Proof Approach
Table of Contents
I rarely repeat talks, but while talking to other speakers I realized I might be the only one doing that, though my sample size is small. While reviewing my site I noticed something strange: one of my very first talks that I gave at Agile Testing Days 2020 opened a different event page. It turned out my slug logic used only the title, so repeating a talk created duplicate URLs. I have three repeated talks over the last five years, enough to show this is not just an edge case but something that needed a scalable fix for SEO and usability.
Here is how I fixed multiple talks with the exact same title produced identical slugs and thus conflicting URLs in a future-proof way that is also SEO-friendly.
The Problem
I rarely give the same talk with the same title. Since my slug logic generated URLs based on the title, this happened:
Speeding up your test execution in a fast-paced world(2021-02-23, Online) >/talks/speeding-up-your-test-execution-in-a-fast-paced-world- Same talk, different event/date (2020-11-10, Agile Testing Days) > same slug!
This caused:
- Clashing pages
- SEO confusion
- Confused user
Classic approaches, like appending the year or city, fail if you repeat talks more than once in a year or at the same place. Adding the conference or event name would solve this on a first thought but it is still possible that the event is the same (e.g. "Online", "Webinar"). Another reason against this is that the URLs would get even longer which I want to avoid.
The Requirements
- No breakage of existing or "canonical" links (SEO + old bookmarks).
- For every future duplicate: URLs must always be unique and stable.
- Zero manual maintenance. No hand-editing slugs or special cases.
The Solution: Unique Slugs via ID Suffix
Rather than rely on talk metadata that might itself collide, I leveraged a data property I know is always unique: the database (array) id field.
- First occurrence: Keeps the original pretty slug (great for established links and nice URLs).
- Subsequent duplicates: Get the slug plus ID:
e.g.,
/talks/speeding-up-your-test-execution-in-a-fast-paced-world-10
With this approach, even if I give a talk with the same title 30 times, each will have a unique, never-colliding, discoverable URL.
Code (simplified):
1function getUniqueTalkSlug(talk, allTalks) {
2 const baseSlug = slugify(talk.title);
3 let seen = 0;
4 for (const t of allTalks) {
5 if (slugify(t.title) === baseSlug) {
6 seen++;
7 if (t.id === talk.id) {
8 return seen === 1 ? baseSlug : `${baseSlug}-${talk.id}`;
9 }
10 }
11 }
12}How This Changed My Workflow (and Could Change Yours)
-
I never have to manually check for collisions.
When I add another instance of the same talk, its slug is always unique by design. -
Legacy links stay valid.
Only the “first” talk with any title gets the plain slug. -
SEO is happy, and so are people!
Every talk page is independently addressable, discoverable, and readable.
Lessons Learned
-
Automate uniqueness early: It’s worth a tiny bit of index logic.
-
Plan for duplicates: Never assume titles or metadata are unique.
-
Preserve legacy links: SEO and users depend on it.
Real-World Impact
After deploying this update my talks page:
- No longer has conflicting URLs.
- Is fully future-proof, with zero extra maintenance for the next talks.
- Is better indexed and more reliable for humans and robots alike.
If you run any site where titles could repeat: conference talks, events, blog posts, whatever, consider this approach!