Hacker News new | past | comments | ask | show | jobs | submit login

A better idea is to use the URI fragment (the string after the # sign). It has the advantage of not having a size limit, and not needing to be sent all to the backend during the request. `window.location.hash` is your friend.

Everything old is new again!

A decade-plus ago, this was common in single-page apps. It was the only way to do it before the history API existed, and enough people were doing it that Google was pushing a fragment-url thing [0] that allowed server-side rendering. You'd make such links in a certain way, then the crawler would hope a simple modification of the URL could be rendered by the server and load that.

(Per a comment on that source, it's not been a thing since 2015, since the google crawler can now handle javascript)

[0] https://stackoverflow.com/questions/6001433/does-google-igno...

Mega.co.nz uses that to hide the decryption key for almost decade. You share links but Mega never knows your key because fragment hash is never sent to server or in referrer. Encrypted files are stored on Mega servers but the decryption occurs in JS on the client side, files are decrypted into temporary JS Blob objects in browser then you save them aka "download" locally... a lot of clever tech there. https://help.mega.io/security/data-protection/end-to-end-enc...

How to use this in React?

I don't think React has anything to do with it. Its just structuring URLs in the browser an appropriate way.

You'd need to read state off the url fragment (location.hash). You can feed that into your appropriate state management system, I suppose. Some (like react router) I think support hash routing, but I don't know that they support both has routing and history routing at the same time, so that may not be quite up to task if thats the case.

This is a great point, but also depends on what browsers you want to support. In my experience some browsers a) will truncate the url when you try to copy it from the browser bar (safari), and b) will not support any url including the hash past a certain cut off (like the SO comment states).

I just updated knotend to use the hashmark, see my comment above!

> It has the advantage of not having a size limit

Still though I suppose you could probably gzip it before base64 encoding it for some additional optimization.

Extremely long URLs have other UX issues, e.g. sending them on chat apps and having them eat up multiple scroll pages in one URL, like:

"Check out this event:

http://..... ... ... (500 scroll-screen-lengths of just URL) ... ...

Here's another event on the same day:

http://..... ... ... (500 scroll-screen-lengths of just URL) ... ...

Can you let me know what you think and which one you'd like to go to?"

The article mentions that compression is already being used.

I don't most chat apps truncate long URLs?

https://app.diagrams.net/ has an excellent example of this. File > Export As > URL...

I just updated knotend so that it now uses the hashmark. I think this is a great idea, and it just loses the ability to get the urls server side, which in my case is totally fine. I also updated the blog post and acknowledged your comment, so thank you!

Sometimes you might want the state on the backend, e.g. to generate open-graph metadata tags.

well you don't have to store ALL of your data this way. Also you can always just choose to send it to the backend still with a POST

Be careful with this. This is only supposed to be used on the client side. Many HTTP server implementations (and infrastructure you run on) will not let you use the URI fragment even if it does hit the wire, or things like caching will break - you almost certainly want use query parameters for anything backend related

URI fragments being client side are entirely their point. Clients should never send them to the server.

Please don't. The web lives and dies by links, the more specific the better, so #to-an-id or #:~:text=to-search are so much more useful than bad state management that probably only works for that one logged-in user anyway. Put that state in the part of the URL you unambiguously control (query params).


That's really interesting. Do you have any idea how much data (i.e. max amount of json) you can store using something like that?

It seems to vary greatly by browser. Based on this SO answer [1] MS edge only supported 2000 characters in 2017, while Chrome currently handles 40 million characters (of compressed, encoded json).

[1] https://stackoverflow.com/a/44532746

Weirdly, with IEs it was exactly 2083 characters (1) not some base 2 number and MS never increased this number over all these years. This upper limit even included fragments. We tried to do something similar as described in the article and were surprised to learn about IEs limitation. In the end, we stored states on a JS object instead using their hash sum as keys and put that inside the fragment. Then fragment based navigation worked like charm across browsers.

(1) https://support.microsoft.com/en-us/topic/maximum-url-length...

I don't quite understand and it's on me, trust me :)

My reading is you were worried about length of encoding one state, so you moved to encapsulating states in a dictionary with keys of hash of State and objects of State

And this led to a decrease in size of the URL?

My guess at my misunderstanding: you kept the state dictionary server-side or at least some other storage method than the URL, and just used the URL to identify which state to use from the dictionary. I e. The bit you add to the URL is just the hash of the state, or dictionary key

Yes, in the final solution we just stored a hash sum inside the URL fragment (I think it was an MD5 sum) and the actual state inside a JS object in main memory. With a page reload you lost all states which was fine for us but you could use session storage to avoid that.

> were surprised to learn about IEs limitation

IE was all about limitations Nothing surprised me about IE limitations.

If you have so many parameters that you need a URL that's over 2048 characters, you should probably be reminded that localStorage exists.

Using local storage means that you can't share a flowchart with someone else (or embed one in another page) at all, let alone easily.

If you need to show a flowchart that doesn't fit in a URL, the idea that you should be able to do this with a URL is kinda bonkers. The solution there would be www.example.com/?data=url_for_the_flowchart_definition, because what you're talking about isn't page state, it's a secondary resource.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact