npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@polingo/web

v0.0.3

Published

Browser adapter for Polingo with fetch loader and localStorage caching

Readme

@polingo/web

npm version npm bundle size

Browser-oriented loader and cache for the Polingo translation engine.

@polingo/web bundles a Fetch-based loader and a resilient localStorage cache so you can use @polingo/core inside traditional SPAs, server-rendered apps that hydrate on the client, or edge runtimes with a compatible fetch implementation.

Contents

  1. What it does
  2. Installation
  3. Quick start
  4. Loader options
  5. Caching behaviour
  6. Usage patterns
  7. Catalog format
  8. Tips & gotchas
  9. Related packages
  10. License

What it does

  • Downloads catalogs via the Fetch API with sensible defaults (/locales/<locale>/<domain>.json).
  • Lets you provide a custom buildUrl, fetch, and RequestInit for CDNs or authenticated endpoints.
  • Ships a storage-backed cache that transparently falls back to memory when localStorage is unavailable.
  • Works together with @polingo/core to provide synchronous translations after the initial preload.
  • Fully typed TypeScript API—great for Next.js, Remix, Astro, Vite, and more.

Installation

npm install @polingo/core @polingo/web
# or
pnpm add @polingo/core @polingo/web
# or
yarn add @polingo/core @polingo/web

Quick start

import { createPolingo } from '@polingo/web';

const polingo = await createPolingo({
  locale: 'en',
  locales: ['en', 'es'],
  loader: { baseUrl: '/i18n' }, // fetches /i18n/en/messages.json, etc.
  cache: true,
  cacheOptions: { prefix: 'my-app', ttlMs: 86_400_000 }, // 24h
});

polingo.t('Welcome');
polingo.tn('{n} item', '{n} items', 3, { n: 3 });

Loader options

WebLoader powers createPolingo under the hood. You can customise it through the loader key or instantiate it yourself.

interface WebLoaderOptions {
  baseUrl?: string; // defaults to '/locales'
  buildUrl?: (locale: string, domain: string) => string; // overrides baseUrl
  fetch?: typeof fetch; // provide for older browsers, React Native, SSR, or tests
  requestInit?: RequestInit; // extra options (credentials, headers, cache directives, ...)
  transformResponse?: (payload: unknown) => TranslationCatalog; // adapt bespoke formats
}

Example: streaming from a CDN with authentication.

const polingo = await createPolingo({
  locale: 'en',
  locales: ['en', 'fr'],
  loader: {
    buildUrl: (locale, domain) => `https://cdn.example.com/static/i18n/${locale}/${domain}.json`,
    requestInit: {
      credentials: 'include',
      cache: 'reload',
    },
  },
});

Caching behaviour

createPolingo enables caching by default (cache: true). Behind the scenes it uses LocalStorageCache, which offers:

  • prefix to namespace entries (defaults to polingo).
  • ttlMs to automatically expire catalogs (unset means persist indefinitely).
  • storage to swap the backing store (useful for testing).

When localStorage is unavailable (SSR, Safari private mode, locked-down WebViews), the cache drops down to an in-memory MemoryCache so translations continue to work, albeit without persistence between reloads.

Disable caching with cache: false if your catalogs are short-lived or you control caching via HTTP headers.

Usage patterns

Single Page Applications

  • Preload the locales you need during app bootstrap to keep translations synchronous.
  • Combine with client-side routing to lazily switch locales via await polingo.setLocale(locale).

Server-Side Rendering / Hydration

  • Run createPolingo only on the client if localStorage is required.
  • For SSR-only environments, manually construct a Translator with WebLoader and NoCache, then hydrate with createPolingo on the client for persistence.

Edge runtimes or React Native

  • Pass an explicit fetch implementation (e.g., from undici, cross-fetch, or the platform) through loader.fetch.
  • Swap the cache for an in-memory implementation if the target does not support localStorage.

Catalog format

By default the loader expects JSON that matches TranslationCatalog from @polingo/core:

{
  "charset": "utf-8",
  "headers": {
    "Plural-Forms": "nplurals=2; plural=(n != 1);"
  },
  "translations": {
    "": {
      "Welcome": {
        "msgid": "Welcome",
        "msgstr": "Bienvenido"
      }
    },
    "menu": {
      "File": {
        "msgid": "File",
        "msgctxt": "menu",
        "msgstr": "Archivo"
      }
    }
  }
}

If your backend returns a different shape, use transformResponse to convert it before it reaches the translator.

Tips & gotchas

  • Serve catalogs with far-future cache headers and rely on ttlMs to refresh them periodically.
  • Handle fetch failures gracefully by catching createPolingo errors during startup and surfacing a user-friendly fallback.
  • When bundling with Vite or Webpack, you can import static catalogs and feed them to a custom loader for fully offline behaviour.
  • Use the same domain names (messages, errors, etc.) clients expect—catalog URLs are derived from the domain.

Related packages

  • @polingo/core – translation runtime (Translator, caches, helpers).
  • @polingo/node – filesystem loader, middleware, and watcher for Node.js.
  • @polingo/react – React hooks, context provider, and Trans component.
  • @polingo/cli – command line tooling for extraction, compilation, and validation.

License

MIT © Reinier Hernández Avila