Skip to content

joinPath function ​

Joins URL path segments with /, ignoring empty segments and collapsing repeated slashes, except the // of a protocol.

ts
import { joinPath } from 'utils';

Signature ​

ts
export function joinPath(...segments: readonly string[]): string

Parameters ​

NameDescription
segmentsThe segments to join, with or without their own slashes.

Returns ​

The joined path.

Example ​

ts
joinPath('https://api.example.com/', '/v1/', 'users'); // 'https://api.example.com/v1/users'
joinPath('/assets', '', 'img/'); // '/assets/img/'

Tests ​

Line coverage: 100 %.

  • ✅ joins ["a","b","c"] as "a/b/c"
  • ✅ joins ["/a/","/b/","c"] as "/a/b/c"
  • ✅ joins ["/assets","","img/"] as "/assets/img/"
  • ✅ joins ["https://api.example.com/","/v1/","users"] as "https://api.example.com/v1/users"
  • ✅ joins ["wss://host//","//x"] as "wss://host/x"
  • ✅ joins ["/","a"] as "/a"
  • ✅ joins ["a//b","c"] as "a/b/c"
  • ✅ joins ["",""] as ""
  • ✅ joins [] as ""

Source ​

src/path/join-path.ts (on GitHub)

Source code
ts
const REPEATED_SLASHES_PATTERN = /(?<!:)\/{2,}/gv;

/**
 * Joins URL path segments with `/`, ignoring empty segments and collapsing repeated slashes, except the
 * `//` of a protocol.
 *
 * @param segments - The segments to join, with or without their own slashes.
 * @returns The joined path.
 * @example
 * joinPath('https://api.example.com/', '/v1/', 'users'); // 'https://api.example.com/v1/users'
 * joinPath('/assets', '', 'img/'); // '/assets/img/'
 */
export function joinPath(...segments: readonly string[]): string {
  return segments
    .filter((segment) => segment !== '')
    .join('/')
    .replaceAll(REPEATED_SLASHES_PATTERN, '/');
}
Test file
ts
import { joinPath } from './join-path';

describe(joinPath, () => {
  it.for([
    [['a', 'b', 'c'], 'a/b/c'],
    [['/a/', '/b/', 'c'], '/a/b/c'],
    [['/assets', '', 'img/'], '/assets/img/'],
    [['https://api.example.com/', '/v1/', 'users'], 'https://api.example.com/v1/users'],
    [['wss://host//', '//x'], 'wss://host/x'],
    [['/', 'a'], '/a'],
    [['a//b', 'c'], 'a/b/c'],
    [['', ''], ''],
    [[], ''],
  ] as const)('joins %j as %j', ([segments, expected]) => {
    expect(joinPath(...segments)).toBe(expected);
  });
});

Keywords: join, path, paths, function

Generated from the JSDoc of the sources.