Generating Random Human-Readable Slugs in JavaScript
Tags: javascript, typescript, webdev, node
Published: 2021-01-14 13:06:56

---
title: Generating Random Human-Readable Slugs in JavaScript 
published: true
description: How to generate random human-readable slugs (e.g., brave-purple-penguin) in JavaScript.
tags: javascript, typescript, webdev, node
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/iqwaaj8a02bgu7fudaoy.jpg
canonical_url: https://typeofnan.dev/generating-random-human-readable-slugs-in-javascript/
---

Often, we'll see random, human-readable slugs (e.g., `brave-purple-penguin`) in the web development world. These slugs offer the uniqueness of a number ID but can be more playful and fun.

<hr />

### Please give this post a 💓, 🦄, and 🔖 if this was useful!

<hr />

# How to Generate Random Slugs

The key to generating random slugs is:

- Identify the parts of speech in each slug position
- Have a list of words for each part of speech
- Randomly select from that list as you iterate through the positions.

For example, a common pattern for these slugs is `adjective-adjective-noun`. You might therefore have a list of adjectives, a list of nouns, and a list of your word order:

```javascript
const adjective = ['blue', 'smiley', 'funny', 'smelly'];
const noun = ['brick', 'kangeroo', 'penguin', 'laptop'];
const words = { adjective, noun };
const order = ['adjective', 'adjective', 'noun'];
```

Then, you can `map` over your order and grab a random element from the corresponding word list:

```javascript
const selected = order.map(partOfSpeech => {
  const choices = words[partOfSpeech];
  return choices[Math.floor(Math.random() * choices.length)];
});
console.log(selected);
// ['funny', 'blue', 'laptop']
```

Finally, you will want to join this array with a `-` character so it's kebob-cased:

```javascript
const slug = selected.join('-');
console.log(slug);
// 'funny-blue-laptop'
```

# Using a Package (I Wrote It!)

Of course, this is a pain because you have to come up with the words yourself and it's not very configurable. Also, you run out of combinations pretty quickly.

To help with this, I made an `npm` package! It's called `random-word-slugs` and it has over 15 million slug combinations (and counting)! Plus, there are a bunch of configuration options, such as being able to specify categories of words that you want.

Read on to see how it works!

# Installation

Install with npm

```bash
npm i random-word-slugs
```

Install with yarn

```bash
yarn add random-word-slugs
```

# Usage

The `random-word-slugs` package can be used without any parameters and defaults to a three-word, kebab-cased slug. **Currently, the default configuration has 15,660,175 unique slug combinations**.

```javascript
import { generateSlug } from 'random-word-slugs';

const slug = generateSlug();
console.log(slug);
// "elegant-green-coat"
```

The `generateSlug` function takes up to two arguments. The first argument is the `numberOfWords` in the slug (defaulting to three) and the secon argument is the package `options`. The following example makes use of both parameters and provides an option to title-case the output:

```javascript
const slug = generateSlug(4, { format: 'title' });
console.log(slug);
// "Elegant Happy Green Coat"
```

# Available Options

The `options` object can have any partial set of the following key/value pairs:

```
{
  format: "kebab" | "camel" | "sentence" | "lower" | "title",
  partsOfSpeech: ("adjective" | "noun")[],
  categories: {
    adjective: ("colors" | "appearance" | etc...)[],
    noun: ("person" | "animals" | etc...)[]
  }
}
```

Note that, if provided, `partsOfSpeech` must be an array the same length as the number of words you're requesting. If using Typescript, the compiler will check this for you.

An example of a completed `options` object might look like this for a three-word slug:

```javascript
const options = {
  format: 'camel',
  partsOfSpeech: ['adjective', 'noun', 'adjective'],
  categories: {
    adjective: ['colors', 'appearance'],
    noun: ['animals'],
  },
};
```

Based on these options, our output might look something like `blueBearTall`.

# Typescript Support for Options

The package exposes a `RandomWordOptions<N>` type, with `N` being the number of words in the slug. If you want to use this type to specify an options object, it might look something like this (although a `Partial` options object is certainly allowed and probably more common):

```typescript
import { RandomWordOptions } from 'random-word-slugs';

const options: RandomWordOptions<3> = {
  format: 'title',
  categories: {
    noun: ['animals', 'places'],
    adjective: ['colors', 'emotions'],
  },
  partsOfSpeech: ['adjective', 'noun', 'adjective'],
};
```

Importantly, the generic `3` here will enforce `partsOfSpeech` being a three-element tuple.

# Categories

The `categories` option allows you to generate your random slug from a subset of categories. Perhaps you only want colorful animals! You can specify one or many categories for the adjectives and nouns that comprise your random slug. The following is a list of categories currently in the repository:

Adjective Categories:

- time
- appearance
- color
- condition
- personality
- shapes
- size
- sounds
- taste
- touch
- quantity

Noun Categories:

- people
- family
- education
- religion
- business
- animals
- transportation
- thing
- technology
- place

# Assessing the Combinatorics

When using the package, you might be curious about how many different slug combinations exist. The package exposes a function to help with this called `totalUniqueSlugs`. This function can be used without arguments and will assume a three-slug `adjective-adjective-noun` format:

```javascript
import { totalUniqueSlugs } from 'random-word-slugs';

const totalSlugs = totalUniqueSlugs();
console.log(totalSlugs);
// 100000
```

**Note:** The `100000` number shown here is just an example and not a representation of the total number of slugs in the package at any moment (that evolves as words are added).

You can also assess the combinatoric space if you have a different number of words, word ordering, or a subset of categories. In the following example, we'll assume a four-word slug, in the order `adjective-noun-adjective-noun`, with only color adjectives and animal nouns:

```javascript
import { totalUniqueSlugs } from 'random-word-slugs';

const totalSlugs = totalUniqueSlugs(4, {
  partsOfSpeech: ['adjective', 'noun', 'adjective', 'noun'],
  categories: {
    adjective: ['colors'],
    noun: ['animals'],
  },
});
console.log(totalSlugs);
// 1000
```

Again, this `1000` is just an example. Importantly, this could help you determine that you're not comfortable with this limited combinatoric space and you can choose to add additional categories.