I'm replacing cookies with localStorage on browsers that can support it (anyone but IE). The problem is site.example
and www.site.example
store their own separate localStorage objects. I believe www
is considered a subdomain (a stupid decision if you ask me). If a user was originally on site.example
and decides to type in www.site.example
on her next visit, all her personal data will be inaccessible. How do I get all my "subdomains" to share the same localStorage as the main domain?

- 23,933
- 14
- 88
- 109

- 19,587
- 34
- 106
- 162
-
5Firefox and IE8 support storing persistent data under a user specified domain. For example on FF, you can do globalStorage['site.com'] and this will be asessible to www.site.com and site.com. I still haven't figured out how to do this in Chrome's implementation. – JoJo Oct 26 '10 at 21:52
-
18Consider using one or the latter -- redirect all users visiting with the www. subdomain to the subdomain-less domain, or the other way around. – Elad Nava Jan 19 '18 at 01:00
-
1I've created article long ago: [Cross-Domain LocalStorage](https://jcubic.wordpress.com/2014/06/20/cross-domain-localstorage/) – jcubic Aug 04 '20 at 11:12
8 Answers
This is how I use it across domains...
- Use an iframe from your parent domain - say
parent.example
- Then on each
child.example
domain, just do a postMessage to yourparent.example
iframe - All you need to do is setup a protocol of how to interpret your postMessage messages to talk to the
parent.example
iframe.

- 23,933
- 14
- 88
- 109

- 2,995
- 2
- 23
- 19
-
2This is the real answer, not the checked off one. I've done this myself but also created a convenient callback wrapper with postMessage. – King Friday Jul 26 '12 at 03:27
-
2Agree with previous commentator. This should work. But its mostly a workaround :) Seems like `localStorage` spec needs to be more flexible. – ValeriiVasin Dec 27 '12 at 08:53
-
1This method allow passing data from any domain to any other domain. It's a workaround, like InviS had said, and it is not the same as sharing the same local storage object on a tld. – oriadam Oct 26 '15 at 11:04
-
5Here's a good article with some example code explaining this method: https://jcubic.wordpress.com/2014/06/20/cross-domain-localstorage/ – Todd Price Feb 04 '16 at 01:58
-
6Note that this is only possible when third-party cookies are not disabled: http://stackoverflow.com/a/44097269/4311428 – maxeh May 21 '17 at 13:14
-
To make make it work with iframe and postMessage you will need to check if url have www and then create iframe without it and if it don't have www you create iframe with www. the page can be the same for both urls. – jcubic Aug 25 '17 at 10:58
-
9Apple has updated the defaults on Safari 7+ both on desktop and mobile to block 3rd party data. The option is now called "Block cookies and other website data" which refers to things like localstorage which are now completely isolated by domain. This method wont work in Safari – Aranganathan Jul 03 '18 at 13:45
-
2@Max @Aranganathan it still *works* for original question case - `site.com`/`www.site.com` as long as subdomains are on the same parent domain – Kostiantyn Jul 24 '19 at 14:43
-
2This is the best answer for the general case of sharing localStorage between two *entirely different* domains. However, when they're related subdomains, there's a similar but MUCH simpler solution, which is to set `document.domain` to the same thing on both parent window and iframe, and then just use the `iframe.contentWindow.localStorage` object in place of `window.localstorage`. Message-posting can be avoided because the windows can interact directly. It's vastly simpler! – Doin Aug 26 '20 at 15:55
-
1@Doin, the ability to set `document.domain` is deprecated now according to https://developer.mozilla.org/en-US/docs/Web/API/Document/domain – Roman Grinev Nov 09 '20 at 20:19
-
So it looks like the postMessage with parent iframe is only solution – Roman Grinev Nov 09 '20 at 20:39
-
1@Roman Yes, it looks that way. The notice about it being deprecated is new - it wasn't there 3 months ago when I posted. It's a shame, because adapting existing code that uses `localStorage` or `indexedDB` to use the much more limited `postMessage()` may often require a complete and complicated re-write... and in the (common) case where all subdomains are in fact parts of the same website, the security concerns around `document.domain` wouldn't seem to apply. – Doin Nov 11 '20 at 08:14
-
1Though this is a solution and an answer to the problem, I'd put some information about how unorthodox this is and shouldn't be done at all. – azevik Dec 22 '20 at 15:05
-
1@azevik Can you explain why this solution is "unorthodox and shouldn't be done at all"? – Tom May 20 '21 at 19:53
-
1@maxeh Third-party cookies doesn't affect using `postMessage`. You can't access `localStorage` of another domain within an `iFrame`, but that `iFrame` can access its own `localStorage` and post it to another. – cyreb7 Dec 06 '21 at 18:17
-
Can anyone point to me to the right article for reactjs? I tried but I couldn't find how to do it in reactjs – Harry May 27 '22 at 07:20
-
@Doin " where all subdomains are in fact parts of the same website, the security concerns around `document.domain` wouldn't seem to apply". What about XSS vulnerabilities? In this case _even_ if you own and control the entire content on both domains, it's safer to have them separated. By merging the two under the same domain as you suggest, then an XSS attack in one will propagate to the other one. – Colm Bhandal Jun 11 '22 at 21:19
-
1@Colm, quite often the decision to use subdomains is made for reasons unrelated to security purposes, so ultimately you'd have to decide whether or not "merging" them this way presents a security risk on a case-by-case basis. But your concern is noted - it's something you should definitely be aware of when using the `document.domain` technique! – Doin Jun 13 '22 at 02:14
If you're using the iframe and postMessage solution just for this particular problem, I think it might be less work (both code-wise and computation-wise) to just store the data in a subdomain-less cookie and, if it's not already in localStorage on load, grab it from the cookie.
Pros:
- Doesn't need the extra iframe and postMessage set up.
Cons:
- Will make the data available across all subdomains (not just www) so if you don't trust all the subdomains it may not work for you.
- Will send the data to the server on each request. Not great, but depending on your scenario, maybe still less work than the iframe/postMessage solution.
- If you're doing this, why not just use the cookies directly? Depends on your context.
- 4K max cookie size, total across all cookies for the domain (Thanks to Blake for pointing this out in comments)
I agree with other commenters though, this seems like it should be a specifiable option for localStorage so work-arounds aren't required.

- 2,651
- 1
- 21
- 28
-
45
-
31Also, as I learned the hard way, the 4k limit is for the sum of the sizes of all cookies for a single domain, not for each cookie. – Blake Miller Aug 11 '15 at 04:37
-
other cons: - cookies will more likely been blocked by adblockers - cookies are intended to be used to share small data betrween server and client, if the server is not using the data you store in the cookie, this is consequently a misuse – Enno Dec 27 '19 at 01:14
-
One more con: On browsers like Safari and Brave, cookies set from the frontend have a max life of 7 days. – Rishabh Poddar Apr 12 '21 at 07:35
I suggest making site.example
redirect to www.site.example
for both consistency and for avoiding issues like this.
Also, consider using a cross-browser solution like PersistJS that can use each browser native storage.

- 23,933
- 14
- 88
- 109

- 86,251
- 24
- 115
- 132
-
I don't have admin access to the servers to do such a redirect. Does that library allow me to share persistent data between www and non-www? After doing some reading, it seems like nearly all browsers' storage mechanisms don't allow it. No matter if it's cookies or localStorage, we're going to run into this problem... – JoJo Oct 26 '10 at 20:05
-
Yes, storage is normally dependent on the domain, including the subdomain. This is why I suggested a redirect. You don't necessarily need admin access, just use an .htaccess rule in the document root – Eran Galperin Oct 26 '10 at 20:57
-
2@JoJo There are several ways to redirect, e.g. by sending the header `Location`, or thru `` HTML tag, or even JS via `window.location`. – Sony Santos Jun 26 '11 at 16:10
-
1
-
1+1 @avoiding, plus this is irrelevant for other cases - like the one for which I'm here lang1.domain.com - lang2.domain.com – r---------k Feb 25 '15 at 21:35
-
You can do it using JS: `if (!/^www/.test(location.hostname)) location.href=location.href.replace('://','://www.')` – oriadam Oct 26 '15 at 11:08
-
Please make www.site.com redirect to site.com for sake of never using www subdomain ever again :) – 3Dom Mar 06 '17 at 02:03
-
1@r---------k not irrelevant, redirect your lang1.domain to domain.com/lang1/ , rewrite to domain.com?l=lang1 finally have your server scripts handle the get to send the appropriate file. – mikakun Oct 31 '22 at 20:04
Set to cookie in the main domain:
document.cookie = "key=value;domain=.mydomain.example"
and then take the data from any main domain or sub domain and set it on the localStorage

- 23,933
- 14
- 88
- 109

- 10,667
- 35
- 107
- 174
-
7
-
2@MuratTutumlu could you please explain more details about your answer? – Kevin O. Dec 15 '22 at 13:00
This is how:
[November 2020 Update: This solution relies on being able to set document.domain
. The ability to do that has now been deprecated, unfortunately. NOTE ALSO that doing so removes the "firewall" between domains and subdomains for vulnerability to XSS attacks or other malicious script, and has further security implications for shared hosting, as described on the MDN page. September 2022 Update: From Chrome v109, setiing document.domain
will only be possible on pages that also send an Origin-Agent-Cluster: ?0
header.]
For sharing between subdomains of a given superdomain (e.g. example.com), there's a technique you can use in that situation. It can be applied to localStorage
, IndexedDB
, SharedWorker
, BroadcastChannel
, etc, all of which offer shared functionality between same-origin pages, but for some reason don't respect any modification to document.domain
that would let them use the superdomain as their origin directly.
(1) Pick one "main" domain to for the data to belong to: i.e. either https://example.com or https://www.example.com will hold your localStorage data. Let's say you pick https://example.com.
(2) Use localStorage normally for that chosen domain's pages.
(3) On all https://www.example.com pages (the other domain), use javascript to set document.domain = "example.com";
. Then also create a hidden <iframe>
, and navigate it to some page on the chosen https://example.com domain (It doesn't matter what page, as long as you can insert a very little snippet of javascript on there. If you're creating the site, just make an empty page specifically for this purpose. If you're writing an extension or a Greasemonkey-style userscript and so don't have any control over pages on the example.com server, just pick the most lightweight page you can find and insert your script into it. Some kind of "not found" page would probably be fine).
(4) The script on the hidden iframe page need only (a) set document.domain = "example.com";
, and (b) notify the parent window when this is done. After that, the parent window can access the iframe window and all its objects without restriction! So the minimal iframe page is something like:
<!doctype html>
<html>
<head>
<script>
document.domain = "example.com";
window.parent.iframeReady(); // function defined & called on parent window
</script>
</head>
<body></body>
</html>
If writing a userscript, you might not want to add externally-accessible functions such as iframeReady()
to your unsafeWindow
, so instead a better way to notify the main window userscript might be to use a custom event:
window.parent.dispatchEvent(new CustomEvent("iframeReady"));
Which you'd detect by adding a listener for the custom "iframeReady" event to your main page's window.
(NOTE: You need to set document.domain = "example.com" even if the iframe's domain is already example.com: Assigning a value to document.domain implicitly sets the origin's port to null, and both ports must match for the iframe and its parent to be considered same-origin. See the note here: https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#Changing_origin)
(5) Once the hidden iframe has informed its parent window that it's ready, script in the parent window can just use iframe.contentWindow.localStorage
, iframe.contentWindow.indexedDB
, iframe.contentWindow.BroadcastChannel
, iframe.contentWindow.SharedWorker
instead of window.localStorage
, window.indexedDB
, etc. ...and all these objects will be scoped to the chosen https://example.com origin - so they'll have the this same shared origin for all of your pages!
The most awkward part of this technique is that you have to wait for the iframe to load before proceeding. So you can't just blithely start using localStorage in your DOMContentLoaded handler, for example. Also you might want to add some error handling to detect if the hidden iframe fails to load correctly.
Obviously, you should also make sure the hidden iframe is not removed or navigated during the lifetime of your page... OTOH I don't know what the result of that would be, but very likely bad things would happen.
And, a caveat: setting/changing document.domain
can be blocked using the Feature-Policy
header, in which case this technique will not be usable as described.
However, there is a significantly more-complicated generalization of this technique, that can't be blocked by Feature-Policy
, and that also allows entirely unrelated domains to share data, communications, and shared workers (i.e. not just subdomains off a common superdomain). @Mayank Jain already described it in their answer, namely:
The general idea is that, just as above, you create a hidden iframe to provide the correct origin for access; but instead of then just grabbing the iframe window's properties directly, you use script inside the iframe to do all of the work, and you communicate between the iframe and your main window only using postMessage()
and addEventListener("message",...)
.
This works because postMessage()
can be used even between different-origin windows. But it's also significantly more complicated because you have to pass everything through some kind of messaging infrastructure that you create between the iframe and the main window, rather than just using the localStorage, IndexedDB, etc. APIs directly in your main window's code.

- 7,545
- 4
- 35
- 37
-
"After that, the parent window can access the iframe window and all its objects _without restriction_" (italics mine). It's the "without restriction" part that worries me. The same worries apply to [this similar answer](https://stackoverflow.com/a/63602446/5134722). Have you considered the security implications of this approach? Presumably, the `www` and non-`www` sites have different content - otherwise why not just redirect - which is why the OP asked this question. But then by this approach, all XSS vulnerabilities of one subdomain get shared with the other, increasing risk. – Colm Bhandal Jun 11 '22 at 21:49
-
1@Colm actually from the wording of the question I get the impression that *site.com* and *www.site.com* *do* access the same pages, and yes - it could therefore be solved with a redirect. It's true there are security implications to using the technique in this answer, but in many cases subdomains may have been used for reasons unrelated to security... so whether this technique introduces an unacceptable risk or not would need to be evaluated individually from website to website. I'm adding a note about security into the answer above. – Doin Jun 13 '22 at 01:54
-
Much appreciated, and I commend you for your service to the community. – Colm Bhandal Jun 13 '22 at 07:47
I'm using xdLocalStorage, this is a lightweight js library which implements LocalStorage interface and support cross domain storage by using iframe post message communication.( angularJS support )

- 3,500
- 2
- 28
- 39
-
3I looked at it, but it looks like it doesn't work on Safari. https://github.com/ofirdagan/cross-domain-local-storage/issues/10 – Andris Zalitis Apr 21 '16 at 09:33
this kind of solution causes many problems like this. for consistency and SEO considerations redirect on the main domain is the best solution.
do it redirection at the server level
How To Redirect www to Non-www with Nginx
or any other level like route 53 if are using

- 3,321
- 2
- 21
- 26
This is how I solved it for my website. I redirected all the pages without www to www.site.example
. This way, it will always take localstorage of www.site.example
Add the following to your .htaccess
, (create one if you already don't have it) in root directory
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]

- 23,933
- 14
- 88
- 109

- 187
- 13
-
11I'm very tempted to downvote this but I won't because it can help the OP's use case, but for people who want to keep sessions across myapp.com and developers.myapp.com and support.myapp.com, this answer is not good. – Don Omondi Oct 16 '17 at 23:59
-
hey @DonOmondi I would appreciate if you can help me with the links for what you are suggesting! – Ayush Baheti Dec 04 '17 at 13:28
-
3The OP asked "use localStorage across subdomains" your answer is "redirect www to non-www" very different things but it can work if and only if the specific subdomain is "www.abc.com" for general cases some other answers here are more practical. – Don Omondi Dec 04 '17 at 23:14