Genshin Impact · interactive maps
Synchronize your map progress.
Switching to a different Genshin map means starting from an empty one - hundreds of chests, oculi and puzzles you already found, all unticked again. This carries them over for you, so you pick up where you left off.
AppSample
Community Genshin map. Progress lives in its Firebase cloud, tied to your Google sign-in.
Sign in on the map, open DevTools → Console, and run the snippet in the instructions below.
Sync into AppSample
Authorize another map above and it will appear here as a source.
HoYoLAB
The official Teyvat Interactive Map. Progress is tied to your HoYoLAB account session.
Open the map signed in, DevTools → Network, click a marker, copy the whole Cookie request header.
Sync into HoYoLAB
Authorize another map above and it will appear here as a source.
How it works
Every map stores progress as its own opaque ids, and none of them offer an import, so there is nothing to hand between them directly. Instead the tool pairs maps by position: it fetches every point each side publishes, works out the coordinate transform between them from the points themselves, and matches each thing you marked to the nearest point of the same category on the other map.
That last step is a nearest-neighbour match, so it is an approximation in principle. In practice the two maps turn out to be the same underlying survey, so the nearest point is almost always the same point: the median gap is 0.05 px on a map tens of thousands of pixels across. A match is only accepted inside a tight radius and only within the same category, and anything that fails those tests is reported as unmatched rather than guessed at - so the risk is a location left for you to do by hand, not a wrong one ticked off.
A few locations sit outside that radius even so - the same orb pinned a couple of metres apart by two sets of contributors. A second pass revisits only what the first one left over, within one category, and pairs two leftovers when each is the other's nearest by a clear margin. Where the leftovers cluster, it leaves them alone: an unmatched location is work left for you, a wrong pair is a lie written into your account.
Nothing is hard-coded to a game version. The transform is re-fitted on every run, including the separate offsets a few regions need.
- Authorize a map - paste its secret and press the button. The card shows how much that account has marked.
- Pick a source - the dropdown lists every other authorized map that can feed this one.
- Preview - see what would change, grouped by category. Nothing is sent.
- Sync - writes the difference. Re-running does nothing the second time.
The maps themselves are not authoritative. Their points are contributed and edited by players, so both sides carry mistakes: a marker a few metres from where the thing actually is, a chest recorded where a puzzle stands, a duplicate, a category someone picked wrongly, or a point one map simply never got. This tool copies what the maps say - it cannot tell a good point from a bad one, so those mistakes come across with everything else. Treat the result as a solid head start rather than a verified inventory, and expect a handful of oddities to sort out in game.
Respawning things are never transferred - ore, wood, plants, enemies, fish, animals. A mark on those means “farmed just now”, which starts a refresh timer, so importing them would write a timestamp that was never true.
Getting your secrets
Each map keeps progress against an account, so the tool needs the session your browser
already has. Run the snippet for a map in its own tab, in the DevTools Console
(Cmd + Opt + I on macOS,
F12 on Windows).
AppSample - Firebase refresh token
Open the AppSample map signed in with Google, then run:
(() => {
const r = indexedDB.open('firebaseLocalStorageDb');
r.onsuccess = () => {
const all = r.result.transaction('firebaseLocalStorage', 'readonly')
.objectStore('firebaseLocalStorage').getAll();
all.onsuccess = () => {
const u = all.result.map(x => x.value).find(v => v && v.uid);
if (!u) return console.error('Not signed in. Click "Sign in with Google" first.');
console.log(u.stsTokenManager.refreshToken);
};
};
})()
It prints one long string. That is the token, and it is long-lived - you do this once.
HoYoLAB - Cookie header
Open the HoYoLAB map
signed in, then DevTools → Network tab → click any marker on the map → find a request to
sg-public-api.hoyolab.com →
Headers → Request Headers → copy the full value of the
Cookie: header.
Running copy(document.cookie)
in the console looks like a shortcut, but the session token that actually proves you are logged in is
httpOnly and invisible to
JavaScript - that snippet silently drops it and pastes something that looks complete but fails
with "please log in first". The Network tab above is the only reliable way to get it.
These are live logins. Treat them like passwords. They are remembered in
this browser's localStorage so a reload re-authorizes without
retyping, and are sent to this server only to make the requests you ask for - never written to its disk,
never logged. Use Forget to remove one from this browser, which reopens the
field so you can paste a different secret. On a shared machine, Forget when you are done.
Caveats
The two maps mostly agree on what a category is, and where they do not, the tool handles it rather than leaving the mismatch to you - in both directions. The ones marked note only are things no tool can fix, listed so a shortfall does not come as a surprise.
Handled
Warming Seelies are ordinary Seelies on AppSample
HoYoLAB files the 33 Warming Seelies under a category of their own. AppSample has no such category: all 462 of its Seelies sit under Seelie, which is exactly HoYoLAB's 429 Seelies plus those 33. They are paired as one category, so a Warming Seelie transfers like any other.
+4
Handled
Shrines of Depths are split by region on HoYoLAB
HoYoLAB gives each region its own Shrine of Depths category - Inazuma, Sumeru, Fontaine, Natlan, Borderland, Snezhnaya, and Mondstadt and Liyue under their bare region names. AppSample keeps all 70 in one. The eight are paired as one category, so a shrine transfers whichever region it is in.
Note only
AppSample only records 54 of the 66 Anemoculi
There are 66 Anemoculi in the game and HoYoLAB lists them all. AppSample records only 54, so a sync into HoYoLAB carries everything you have marked and still leaves 12 unticked, and going the other way there is nothing on AppSample for them to land on. Those 12 are yours to finish by hand.
Anything a caveat does not cover is paired by its own category alone, and a location with no counterpart is reported as unmatched rather than matched to something else.