Skip to Content
  • Website
Codsen
  • Home
  • Open Source
  • Articles
  • About

prevOpen Source→is-relative-urinext

is-relative-uri5.2.0

Is given string a relative URI?

Downloads per monthChangelogMIT Licenselibera manifesto
  • the top
  • Installation
  • Quick Take
  • Examples
  • BACKGROUND
  • VALIDATING TH…
  • API — ISREL()
  • API — DEFAULTS
  • API — VERSION
  • OPTS — FLAGUPURISWIT…
  • Changelog

Installation

Quick Take

Examples

  • Invalid URI characters
  • URI scheme detection
  • A valid relative URI

Background

It’s easy to validate the absolute URL’s:

<a href="https://www.npmjs.com">z</a>

It’s harder to validate relative URL’s:

<a href="//example.com/path/resource.txt">z</a>
<a href="/path/resource.txt">z</a>
<a href="path/resource.txt">z</a>
<a href="/path/resource.txt">z</a>
<a href="../resource.txt">z</a>
<a href="./resource.txt">z</a>
<a href="resource.txt">z</a>
<a href="#fragment">z</a>

But spec-wise, at least theoretically, these are also correct values (see wikipediaopens in a new tab for more).

Considering the base URI of http://a/b/c/d;p?q, the following URI’s would get resolved accordingly:

<a href="g:h">z</a>     -> "g:h"
<a href="g">z</a>       -> "http://a/b/c/g"
<a href="./g">z</a>     -> "http://a/b/c/g"
<a href="g/">z</a>      -> "http://a/b/c/g/"
<a href="/g">z</a>      -> "http://a/g"
<a href="//g">z</a>     -> "http://g"
<a href="?y">z</a>      -> "http://a/b/c/d;p?y"
<a href="g?y">z</a>     -> "http://a/b/c/g?y"
<a href="#s">z</a>      -> "http://a/b/c/d;p?q#s"
<a href="g#s">z</a>     -> "http://a/b/c/g#s"
<a href="g?y#s">z</a>   -> "http://a/b/c/g?y#s"
<a href=";x">z</a>      -> "http://a/b/c/;x"
<a href="g;x">z</a>     -> "http://a/b/c/g;x"
<a href="g;x?y#s">z</a> -> "http://a/b/c/g;x?y#s"
<a href="">z</a>        -> "http://a/b/c/d;p?q"
<a href=".">z</a>       -> "http://a/b/c/"
<a href="./">z</a>      -> "http://a/b/c/"
<a href="..">z</a>      -> "http://a/b/"
<a href="../">z</a>     -> "http://a/b/"
<a href="../g">z</a>    -> "http://a/b/g"
<a href="../..">z</a>   -> "http://a/"
<a href="../../">z</a>  -> "http://a/"
<a href="../../g">z</a> -> "http://a/g"

Validating them all

As you saw, relative URI’s can be pretty much anything, including empty string and random letters like zzz.

What do you do?

The only thing left is to try to catch bad patterns.

Conceptually, this program tells if a given string is not messed up from the perspective of relative URI pattern, as far as our imperfect algorithm sees.

Mainly: no whitespace, no repeated things (triple slashes or double question marks), no slashes or dots after a hash, two dots must not be followed by a letter and others.

API — isRel()

The main function isRel() is imported like this:

It’s a function which takes two input arguments:

Input argumentTypeObligatoryDescription
str
Type: String
Obligatory: no
strStringnoThe extracted value of HTML media attribute or CSS media query without @media or opening bracket.
opts
Type: Plain object
Obligatory: no
optsPlain objectnoOptional Options Object.

If passed str is not a string, an error will be thrown.

The optional options object has the following shape:

KeyTypeDefaultDescription
flagUpUrisWithSchemes
Type: boolean
Default: true
flagUpUrisWithSchemesbooleantrueYield false on URI’s with scheme (https:// for example)?

Function returns a plain object:

For example:

{
  res: false,
  message: `Two consecutive hashes.`
}

or if schema-URI’s are flagged up via opts.flagUpUrisWithSchemes, the message value can be null:

{
  res: false,
  message: null
}

or

{
  res: true,
  message: null
}

False res and null message happens only on schema-URI’s. By checking is message set, you find out, were there real errors.

API — defaults

You can import defaults:

It's a plain object:

The main function calculates the options to be used by merging the options you passed with these defaults.

API — version

You can import version:

opts.flagUpUrisWithSchemes

When validating the URI’s which can be relative (for example, href attribute values) one should use two libraries: one to check strict URI’s (those with schema) and one with relative URI’s (those without schema).

For example, is-url-superbopens in a new tab and this package.

If opts.flagUpUrisWithSchemes is set to true, this program will search for schemes and yield a falsy result if it detects a known <scheme>: for example mailto:.

Another challenge: URI with schema-as-error is not the same “error” — it’s not a “real error”. To distinguish the two, the program sets result object’s key message to null.

That is, seemingly correct URI will have a message null:

import { isRel } from "is-relative-uri";
const str = `https://codsen.com`;
const res = isRel(str, { flagUpUrisWithSchemes: true });
console.log(JSON.stringify(res, null, 4));
// => {
//      res: false,
//      message: null
//    }

Changelog

Open Changelog
↑ back to top
prev next

Copyright

All rights reserved © Roy Revelt 2026
All our open source packages are under MIT licenceopens in a new tab

Activities

🐛 See a bug? Raise an issueopens in a new tab
💘 Check out the Indiewebopens in a new tab and Libera manifestoopens in a new tab