Made in Builder

Made in Builder.io

Live Demo 👉 All Demo, No Pitch: Content & Commerce / Builder.io & Elastic Path on 12/13

×

Developers

Product

Use Cases

Pricing

Developers

Resources

Company

Get StartedLogin

Product

Features

Integrations

Talk to an Expert

Pricing

Blog

Home

Resources

Blog

Forum

Github

Login

Signup

×

Visual CMS

Drag-and-drop visual editor and headless CMS for any tech stack

Theme Studio for Shopify

Build and optimize your Shopify-hosted storefront, no coding required

Resources

Blog

Get StartedLogin

‹ Back to blog

WEB DEVELOPMENT

Safer URL reading and writing in modern JavaScript

January 10, 2023

Written By Steve Sewell

You might unknowingly be writing URLs in an unsafe way

Can you spot the bug in this code?

There are at least three!

We will break them down below:

Common issue #1: incorrect separator characters

A URL string with an extra `?`

Oops! This is certainly a newbie mistake, but one so easy to miss I’ve caught this in my own code even after 10 years of JS development.

A common culprit for this in my experience is after editing or moving code. For example, you have a correctly structured URL, then copy one piece from one to another, and then miss that the param separator was wrongly ordered.

This can also happen when concatenating. For instance:

But wait, the original url may have had a query param in it. Ok, so this should be:

But wait, if the original url didn’t have query params then this is now wrong. Argh.

Common issue #2: forgetting to encode

A URL string with a param without encoding

Gah. model and locale likely don’t need to be encoded, as they are URL-safe values, but I didn’t stop to think text can be all kind of text, including whitespace and special characters, which will cause us problems.

So maybe we’ll overcorrect and play things extra safe:

But things are feeling a little…uglier.

Common issue #3: accidental whitespace characters

A URL string with accidental whitespace characters

Oof. In order to break this long URL into multiple lines, we accidentally included the newline character and extra spaces into the URL, which will make fetching this no longer work as expected.

We can break the string up properly now, but we’re getting even messier and harder to read:

That was a lot just to make constructing one URL correct. And are we going to remember all this next time, especially as that deadline is rapidly approaching and we need to ship that new feature or fix asap?

There has to be a better way.

A gif of Joey from friends saying "There's gotta be a better way!"

The URL constructor to the rescue

A cleaner and safer solution to the above challenge is to use the URL constructor:

This solves several things for us:

  • Separator characters are always correct (? for the first param, and thereafter).
  • All params are automatically encoded.
  • No risk of additional whitespace chars when breaking across multiple lines for long URLs.

Modifying URLs

It is also incredibly helpful for situations where we are modifying a URL but we don’t know the current state.

For instance, instead of having this issue:

We can instead just do:

Similarly, you can also write other parts of the URL:

Reading URL values

Now, the age-old problem of “I just want to read a query param from the current URL without a library” is solved.

Or for instance update the current URL with:

But this is not just limited to the browser. It can also be used in Node.js

As well as Deno:

URL properties to know

URL instances support all of the properties you are already used to in the browser, such as on window.location or anchor elements, all of which you can both read and write:

Or, at a glance:

A diagram of a URL and arrows pointing to each segment such as where the "hostname" vs "hash" and so on ≠are.

URLSearchParams methods to know

The URLSearchParams object, accessible on a URL instance as url.searchParams supports a number of handy methods:

searchParams.has(name)

Check if the search params contain a given name:

searchParams.get(name)

Get the value of a given param:

searchParams.getAll(name)

Get all values provided for a param. This is handy if you allow multiple values at the same name, like &page=1&page=2:

searchParams.set(name, value)

Set the value of a param:

searchParams.append(name, value)

Append a param — useful if you potentially support the same param multiple times, like &page=1&page=2:

searchParams.delete(name)

Remove a param from the URL entirely:

Pitfalls

The one big pitfall to know is that all URLs passed to the URL constructor must be absolute.

For instance, this will throw an error:

You can resolve that, by providing an origin as the second argument, like so:

Or, if you truly need to only work with URL parts, you could alternatively use URLSearchParams directly if you just need to work with query params of a relative URL:

URLSearchParams has one other nicety as well, which is that it can take an object of key value pairs as its input as well:

Browser and runtime support

new URL supports all modern browsers, as well as Node.js and Deno! (source)

A table of browser support - which you can get to in the "source" link above.

Visually build with your components

Builder.io is a Visual CMS that let's you drag and drop to create content on your site visually, using your components.

Stop drowning in a backlog of requests - build with your whole team instead.

Try it out
Learn more

Share

Twitter
LinkedIn
Facebook

Continue Reading
Web Performance14 MIN
Optimal Images in HTML
WRITTEN BYSteve Sewell
January 26, 2023
web development9 MIN
The Tailwind CSS Drama Your Users Don't Care About
WRITTEN BYYoav Ganbar
January 25, 2023
Web Development9 MIN
Fast and Light Relative Time Strings in JS
WRITTEN BYSteve Sewell
January 24, 2023

Product

Visual CMS

Theme Studio for Shopify

Sign up

Login

Featured Integrations

React

Angular

Next.js

Gatsby

Get In Touch

Chat With Us

Twitter

Linkedin

Careers

© 2020 Builder.io, Inc.

Security

Privacy Policy

Terms of Service

Visually build and optimize digital experiences on any tech stack. No coding required, and developer approved.

Sign up

Log in

DEVELOPERS

Builder for Developers

Developer Docs

Github

JSX Lite

Qwik

INTEGRATIONS

React

Angular

Next.js

Gatsby

PRODUCT

Product features

Pricing

RESOURCES

User Guides

Blog

Forum

Templates

COMPANY

About

Careers 🚀

Visually build and optimize digital experiences on any tech stack. No coding required, and developer approved.
Get Started
Log in

DEVELOPERS

Builder for Developers

Developer Docs

Open Source Projects

Performance Insights

PRODUCT

Features

Pricing

RESOURCES

User Guides

Blog

Community Forum

Templates

Partners

Submit an Idea

INTEGRATIONS

React

Next.js

Gatsby

Angular

Vue

Nuxt

Hydrogen

Salesforce

Shopify

All Integrations

Security

Privacy Policy

Terms of Service

By clicking “Subscribe”, I agree to Builder.io's Terms of Service and Privacy Policy.