Mac
Mac

Reputation: 334

Using window.history.pushState multiple times, for a URL with multiple /

So I'm trying to achieve that when a user first chooses a category (from a list or something similar) the URL will go from

www.website.com/products/
to
www.website.com/products/category1

The user the gets presented with multiple subcategories, and when a user proceed to choose one of those, i want the URL go from:

www.website.com/products/category1
to
www.website.com/products/category1/subcategory1

For a illustration, see this

Regardless i have played around with the .pushState, and it works great for my category1, but when i press the subcategory1-2-3, it just keeps adding the stuff to the URL.
In my first event handler i do:

window.history.pushState(null, null, jQuery(this).attr('category'));

and that gives me the correct address im looking for /products/category1/ But when i then try to do:

window.history.pushState(null, null, jQuery(this).attr('category') + "/" + jQuery(this).attr('subcategory'));

It will simply just keep adding stuff to my URL, what exactly am i doing wrong here?

Upvotes: 0

Views: 2250

Answers (1)

gyre
gyre

Reputation: 16777

The problem is that your URLs are relative to the current directory, which means that category/sub-category points to a different location depending on whether you are viewing https://example.com/products/category or https://example.com/products/category/sub-category.

You can see how the error accumulates by running the snippet below:

var url = 'http://example.com/products/'

function parseRelative (url, base) {
  console.log(
    'Relative: ', url,
    '\nBase:\t  ', base,
    '\n    =>    ', url = new URL(url, base).href
  )
  return url
}

for (var i = 0; i < 3; i++) {
  url = parseRelative('category/sub-category', url)
}
.as-console-wrapper { min-height: 100%; }

Fixing the problem simply requires changing your URLs to the path-absolute form /products/...:

$('.example-button').click(modifyUrl)

function modifyUrl() {

  var url = '/products/' + [$(this).attr('data-category'), $(this).attr('data-sub-category')].join('/')

  history.pushState(null, '', url)
  
  console.log(location.href)

}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="example-button" data-category="category" data-sub-category="sub-category">Click Me!</button>

Upvotes: 1

Related Questions