Skip to content

Instantly share code, notes, and snippets.

@Lachee
Last active December 11, 2022 17:33
Show Gist options
  • Save Lachee/616d8cb2508c7ef22d7d54121f39aa49 to your computer and use it in GitHub Desktop.
Save Lachee/616d8cb2508c7ef22d7d54121f39aa49 to your computer and use it in GitHub Desktop.
Svelte CloudFlare Polyfil
/**
This polyfil solves some of the issues svelte's cloudflare adapter has with goto and localStorage being.... iffy.
This will polyfil the goto as a stub for SSR and polyfil the localStorage as a simple array storage.
Feel free to implement your own polyfils for localStorage to actually be useful too, i only request you share it forwards.
Author: Lachee
License: MIT (do what you want)
Date: 12/12/2022
*/
import { browser } from '$app/environment';
/**
* Returns a Promise that resolves when SvelteKit navigates (or fails to navigate, in which case the promise rejects) to the specified `url`.
*
* @param url Where to navigate to. Note that if you've set [`config.kit.paths.base`](https://kit.svelte.dev/docs/configuration#paths) and the URL is root-relative, you need to prepend the base path if you want to navigate within the app.
* @param opts Options related to the navigation
*/
export async function goto(url : string | URL, opts?: {
/**
* If `true`, will replace the current `history` entry rather than creating a new one with `pushState`
*/
replaceState?: boolean;
/**
* If `true`, the browser will maintain its scroll position rather than scrolling to the top of the page after navigation
*/
noScroll?: boolean;
/**
* If `true`, the currently focused element will retain focus after navigation. Otherwise, focus will be reset to the body
*/
keepFocus?: boolean;
/**
* The state of the new/updated history entry
*/
state?: any;
/**
* If `true`, all `load` functions of the page will be rerun. See https://kit.svelte.dev/docs/load#invalidation for more info on invalidation.
*/
invalidateAll?: boolean;
}) : Promise<void> {
if (browser) {
const { goto: goto2 } = await import('$app/navigation')
await goto2(url, opts);
}
}
class PolyfilStorage implements Storage {
private _data : Record<string, string> = {};
get (name : string) : any {
return this._data[name];
}
get length() {
return Object.keys(this._data).length;
}
clear(): void {
throw new Error('Method not implemented.');
}
getItem(key: string): string | null {
return this._data[key] ?? null;
}
key(index: number): string | null {
return Object.keys(this._data)[index];
}
removeItem(key: string): void {
delete this._data[key];
}
setItem(key: string, value: string): void {
this._data[key] = value;
}
}
export const localStorage : Storage = (() => {
if (browser && typeof window == 'object' && typeof window.localStorage == 'object')
return window.localStorage;
return new PolyfilStorage();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment