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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@stringpush/sdk

v0.3.1

Published

Plain JS SDK for in-context translation

Readme

@stringpush/sdk

Framework-agnostic plain JavaScript SDK for StringPush.

Install

pnpm add @stringpush/sdk

Usage

import { init, setLocale, t } from "@stringpush/sdk";

await init({
  applicationId: "your-application-id",
  environment: "staging",
  locale: "en",
  apiKey: "trt_…",
  apiBaseUrl: "https://api.platform.stringpush.com",
  origin: "https://your-app.example.com",
  onLocaleChange: () => app.rerender(),
  onTranslationsUpdated: () => app.rerender(),
});

console.log(t("common.greeting"));
console.log(t("common.welcome", { name: "Ada" }));
console.log(t("items.count", { count: 3 }));

await setLocale("fr");

init fetches the manifest and active locale bundle using the runtime API key. Bundle URLs from the manifest are resolved against apiBaseUrl.

MAU reporting (optional)

await init({
  // …same as above
  reportUsage: true, // POST /v1/usage/mau after init (SHA-256 of anonymous localStorage id)
});

Enable when your plan includes MAU metering. No PII is sent — only a stable hash per browser per calendar month.

t(key, values) supports ICU MessageFormat (plural, select) and {name} interpolation via intl-messageformat. Configure missing-key behavior with missingKeyFallback (key, default_message, or empty) and optional defaultMessages at init.

Try the hosted sample app or follow Getting started.

Staging vs production

Pass environment: "staging" or environment: "production" in init(). The manifest and bundle URLs are scoped per environment (/bundles/{projectId}/staging/… vs …/production/…). Use staging for pre-release copy and overlay edit mode; use production for live customer traffic after promote + publish in admin.

Overlay edit mode is intended for staging only unless your organization explicitly enables production overlay in admin Settings (Business+).

Edit mode (staging overlay)

Recommended: edit launcher (M2-SDK-05)

Arm with ?translation_edit=1 only — a Translate FAB appears (staging). Click Translate to open an admin popup for sign-in (or enable overlay immediately when a stored edit token exists). JWT is stored in sessionStorage, not left in the query string.

await init({
  /* … */
  environment: "staging",
  editLauncher: {
    signInUrl: "https://admin.example.com/overlay-grant",
    // signInMode: "redirect" — full-page navigation instead of popup
    // or requestEditToken: async () => { … } // demo/local only
  },
});

Optional shared secret: ?translation_edit=1&translation_edit_key=<armingKey> when editLauncher.armingKey is set.

When already signed into admin, the popup mints an edit token and closes automatically. Otherwise complete login in the popup; the customer page stays open.

Magic link (auto-enable)

?translation_edit=1&edit_token=<jwt> still auto-enables overlay on load (QA links).

Programmatic

await init({ /* … */ editToken: "<jwt>" });
await enableEditMode();
disableEditMode();

The overlay UI, launcher, and WebSocket client load in separate chunks (not in the default import bundle).

Key resolution (edit mode)

Mark translatable nodes with data-i18n-key="your.key" or register a DOM resolver:

import { registerResolver } from "@stringpush/sdk";

registerResolver((element) => (element.id === "title" ? "home.title" : null));

Or mark nodes with data-i18n-key="your.key" (see exported constant I18N_KEY_ATTR).

In edit mode, hovering or focusing a resolved element shows a highlight and the key path. Click a highlighted element to open the side panel and edit values for all project locales (saved via PATCH /v1/overlay/values with the edit JWT). After a successful save, the in-memory catalog for the active locale updates and onTranslationsUpdated runs.

If another editor changed the same value, the panel shows a 409 conflict banner with a reload option.

While edit mode is active, the overlay WebSocket applies translation.updated (same environment, with version guards) to the in-memory catalog, refreshes an open edit panel for the same key, and refetches the manifest when a newer bundle.published arrives for the active locale — all invoke onTranslationsUpdated. The client reconnects automatically if the socket drops.

Security notes

  • Runtime key (trt_…): read-only; safe in customer frontends; restrict via application allowed domains.
  • Edit token: short-lived; overlay/write only; never commit or ship in production bundles.
  • Environment: use staging for overlay QA; production edit requires production overlay enabled in admin Settings (Business+).
  • Origin: set origin in init() to match an allowlisted domain (defaults to window.location.origin).

Report vulnerabilities to [email protected].

Troubleshooting

| Symptom | What to check | |---------|----------------| | Manifest 401 / 403 | Runtime API key; Origin header vs verified allowlisted domains | | Overlay 403 | Page Origin not verified for this application | | edit token required | Pass editToken, or ?translation_edit=1&edit_token= | | edit token is malformed | JWT truncated in URL — use encodeURIComponent | | environment does not match | init({ environment }) must match the edit session environment | | 401 on overlay save | Edit JWT expired — click Sign in again in the panel or use the Translate bar to re-grant via admin | | 409 on save | Another editor saved first — use Reload in the panel | | Live updates missing | Confirm staging overlay and realtime are enabled for your org; same project/environment as the edit session | | CORS errors on manifest or overlay | Origin must be verified in admin — see Verify a browser origin | | CORS errors on bundle CDN | Hosted CDN allows *; SDK omits runtime key on cross-origin bundle URLs. BYO CDN: set Access-Control-Allow-Origin: * (or your origins) on bundle GET |

Full staging setup: Staging overlay.

See Concepts overview for the full integration model.