A mongoose plugin that generates slugs and manages slug aliasing

Usage no npm install needed!

<script type="module">
  import mongooseDocumentSlugs from '';


CircleCI Coverage Status bitHound Overall Score bitHound Dependencies bitHound Dev Dependencies bitHound Code

Mongoose Document Slugs

Mongoose document slugs is a plugin for the Mongoose ORM. This plugin will generate slugs from a given field automatically upon document creation. When the document slug is modified, the previous slug value will be retained as an alias. This means that if the document is searched for via it's previous slug it can still be found. Note that if another document's slug is set to the value of an existing alias, the alias is removed, and the document takes ownership of the slug.


First things first you need to add the plugin to your schema.

const mongoose      = require('mongoose');
const Schema        = mongoose.Schema;
const mongooseSlugs = require('mongoose-slugs');

const postSchema = new Schema({
  title: { type: String },
  body : { type: String }
postSchema.plugin(mongooseSlugs, { sourceField: 'title' });

mongoose.model('Post', postSchema);

In the example above we create a postSchema then register it as a model. Typically blogs have slugs for each post, allowing the software to have pretty urls that humans can remember and recognize. By adding Mongoose Slugs as a plugin for the postSchema, and telling it to use the title field is our sourceField, Mongoose Slugs will automatically generate a slug for new post documents from the title automatically.

const Post = mongoose.model('Post');

const post = new Post({ title: 'My day at the beach :)', body: '...' }); => {
  post.slug === 'my-day-at-the-beach'

Slug collisions

Mongoose Document Slugs will prevent slug collisions by suffixing slugs with a dash and a number. This works by performing a count on the collection the and finding a single document with matching slug. If found a findOne is preformed using a regex matching the slug with a suffix present. The sort order is set so the document with the largest suffix is returned. If no result is found then '-1' is added to the end of the slug. Otherwise the tool will add 1 to the suffix number and append it to the slug.

const Post = mongoose.model('Post');

const post = new Post({ title: 'My day at the beach :)', body: '...' });

// my-day-at-the-beach-1, my-day-at-the-beach-2, and my-day-at-the-beach-3
// already exist. => {
  post.slug === 'my-day-at-the-beach-4'