Making list formatting easy with Intl.ListFormat

Introduction

Let's say you have an array containing your favorite dog breeds:

const favoriteDogs = ['Corgi', 'German Shepherd', 'Goldendoodle'];

Your goal is to format that list as a string like "Corgi, German Shepherd, and Goldendoodle." One option is to write a basic utility function like this:

function formatList(list) {
    if (!list?.length) {
        return "";
    }
    if (list.length === 1) {
        return list.toString();
    }
    if (list.length === 2) {
        return list.join(' and ');
    }

    return list.slice(0, -1).join(', ') + ', and ' + list.slice(-1);
};

But we'd need to make modifications if we wanted to use or instead of and, omit the Oxford comma, or handle different languages. Instead, let's see how we can use Intl.ListFormat to have JavaScript do this heavy lifting for us.

Intl.ListFormat

Intl.ListFormat replaces formatList with a couple of lines of code:

const lf = new Intl.ListFormat('en');
lf.format(favoriteDogs);
// > Corgi, German Shepherd, and Goldendoodle

Intl.ListFormat comes from Intl, which is a built-in object that provides language-sensitive functions. We've provided en (English) as the locales argument, which formats the list based on the language or region.

This gives us a lot of localization power with little effort. For instance, we can specify zh for traditional Chinese and let it localize the conjunction and punctuation for us:

const lf = new Intl.ListFormat('zh');
lf.format(['咖啡', '茶', '可樂']);
// > 咖啡、茶和可樂 (Coffee, tea and coke)

Other formatting options

We can optionally specify a second options argument that has a style and type property. style is the length of the output and can be long (the default), short or narrow:

new Intl.ListFormat('en', { style: 'short' }).format(favoriteDogs);
// > Corgi, German Shepherd, & Goldendoodle
new Intl.ListFormat('en', { style: 'narrow' }).format(favoriteDogs);
// > Corgi, German Shepherd, Goldendoodle

type describes the list type, which is conjunction (and-based) by default. It can be used to make our list disjunctive or suitable for units:

new Intl.ListFormat('en', { type: 'disjunction' }).format(favoriteDogs);
// > Corgi, German Shepherd, or Goldendoodle
new Intl.ListFormat('en', { type: 'unit' }).format(['6 feet', '2 inches']);
// > 6 feet, 2 inches

Conclusion

Instead of writing a list formatting function, consider using Intl.ListFormat. There are a lot of other useful functions from Intl, too; check them out at MDN.

Thanks for reading!

References

Let's connect

If you enjoyed this post, connect with me on Twitter, LinkedIn, and GitHub! You can also subscribe to my mailing list and get the latest content and news from me.

22