I’ve been putting off implementing URL slugs on my website for ages. But as the website is ready and I want it to grow, I knew it was time to pull up my sleeves and start figuring out how best to do it.
For those who aren’t familiar with URL slugs, it’s when a website URL contains the title of the page. Kind of like this:
thiscodeworks.com/the-title-of-this-blog
In my first blog post for thiscodeworks.com I narrate my search for the best express package to do this and how I got it to work.
Why use URL slugs?
Well it doesn’t make an impact on the running of the website, but it does help with Search Engine Optimization (SEO). If you want your website to rank high on Google search results, then url-slugs can help.
For posts on your site a URL slug that contains the title of the post or the keyword you are optimizing for can boost your ranking in search results. Basically, it’s an easy way to attract some organic traffic.
The packages I tested to “slugify” URLs
I know Express should make the whole process easy. Just install a package, and you get the functionality. But it really isn’t that easy. Because you need to:
- find the right package,
- figure out how to integrate it with your code following one or two examples (sometimes there aren’t any examples at all), and
- troubleshoot on your own — there’s no technical support and not much help on forums unless the package is really popular..
I started off with one recommended on Stackoverflow called Mongoose URL Slugs. The installation and usage seemed easy enough, but the minute I ran it my website crashed. I got
MongoError: E11000 duplicate key error index: lthiscodeworks.codeposts.$myslug_1 dup key: { : null }
Apparently other people had run into the same issue, but there wasn’t a solid way to resolve it. I spent 2 days in the few hours free from work fiddling around and trying to understand the issue. But nothing was working. So I moved onto another package — slugify.
Slugify was easy to implement, and it was able to turn a string of text into a slug. But then came the question: how on earth do I slugify a field and then store that value in another field in a schema? I’m sure there’s an easy solution here, but I couldn’t find a way to refer to a field within the same schema and then run a plugin on that.
Moving on…. I found mongoose-slug-generator.
This one did exactly what I wanted. It was able to slugify a field and then store that value into a seperate field within the schema. Yes!!
Installing mongoose-slug-generator
If anybody is interested, here’s how it works:
Step 1: Run the following in terminal:
npm install mongoose-url-slugs
Step 2: Initialize and add code to schema model
var mongoose = require(‘mongoose’);
var Schema = mongoose.Schema;
var slug = require(‘mongoose-slug-generator’);mongoose.plugin(slug);
const pageSchema = new Schema({
title: { type: String , required: true},
slug: { type: String, slug: “title” }
});var Page = mongoose.model(‘Page’, pageSchema);
module.exports = Page;
Taa daa!
Adding the slug to a page’s URL
Previously my pages were rendered based on their ID. I wanted to move from
thiscodeworks.com/98765
to
thiscodeworks.com/title-of-page/98765.
Truth be told, I would rather get rid of the id number entirely in the URL, but because it will always be unique as opposed to a slug I decided to keep it.
Here’s a simplification of the new route I used to include slugs in the URL:
app.get('/:slug/:id', (req,res,next)=>{
Page.findById(id, function (err, page) { res.send('hello world')
});
})
;
Only drawback of implementing this code was that I had to update every document of that model. That took a while, and I lost a lot of time. But it had to be done. Also, I got to do some cleaning as it forced me to look at posts that were leftover from testing and not necessary anymore.
Although this code works for me, I’m sure there is a better and cleaner way to do this. If you’re one of those geniuses who does know, send me an email at thiscodeworks.com@gmail.com and I’ll add your suggestion here.
Originally published at www.thiscodeworks.com.