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

@daeuk1011/google-news-url-decoder

v0.2.2

Published

Decode Google News article share URLs to their original article URL.

Readme

google-news-url-decoder

Decode Google News article share URLs to their original article URL. Rust core, WebAssembly distribution.

Ported from SSujitX/google-news-url-decoder (Python).

Install

npm install @daeuk1011/google-news-url-decoder

Requires a JS runtime with global fetch: Node.js 18+, Cloudflare Workers, Deno, Bun.

Browser is not supported. news.google.com does not return CORS headers to third-party origins. Use this library from a server, Worker, or extension context instead.

Usage

import { decode, DecodeError } from "@daeuk1011/google-news-url-decoder";

try {
  const url = await decode("https://news.google.com/articles/CBMi...");
  console.log(url);
} catch (err) {
  if (err instanceof DecodeError) {
    console.error(err.kind, err.message);
  }
}

Decoding many URLs

decodeBatch decodes a list of URLs and collapses the final decode step into batched batchexecute POSTs — one request per batchSize URLs instead of one per URL. This sharply cuts the request volume on the rate-limited endpoint. Per-URL failures are isolated: results are returned in input order, each either { url, decoded } or { url, error }.

import { decodeBatch } from "@daeuk1011/google-news-url-decoder";

const results = await decodeBatch(urls, { batchSize: 50, concurrency: 20 });

for (const r of results) {
  if (r.decoded) console.log(r.decoded);
  else console.error(r.url, r.error.kind);
}

A per-article params GET is still required for each URL (the signature is per-article), so at scale you still want a rotating proxy pool — batching only reduces the POST volume.

Options

decode(url, {
  fetch,    // custom fetch implementation (default: globalThis.fetch)
  headers,  // extra headers (merged over default User-Agent)
  signal,   // AbortSignal forwarded to every fetch call
});

decodeBatch(urls, {
  fetch, headers, signal,  // same as decode
  batchSize,  // URLs per batchexecute POST (default 50; server tolerates 150+)
  concurrency, // max concurrent param GETs in flight (default 20)
});

Using a proxy (Node.js)

import { fetch as undiciFetch, ProxyAgent } from "undici";
const dispatcher = new ProxyAgent("http://user:pass@host:8080");
const fetch = (url, init) => undiciFetch(url, { ...init, dispatcher });

const decoded = await decode(googleUrl, { fetch });

Error model

All failures throw DecodeError. Branch on err.kind:

| kind | Cause | |---|---| | invalid-url | Input is not a recognized Google News article URL. | | fetch-failed | A fetch call rejected, returned a non-2xx status, or its body could not be read. | | rate-limited | Google throttled the request (HTTP 429 or a redirect to its /sorry/ abuse page). Back off and retry, ideally from a different IP. | | params-missing | Google returned HTML without the expected data-n-a-sg / data-n-a-ts attributes. | | parse-failed | The batchexecute response did not match the expected nested-JSON shape (likely an upstream format change). |

Runtime support

| Runtime | Supported | Notes | |---|---|---| | Node.js 18+ | ✅ | Uses global fetch. | | Cloudflare Workers | ✅ | See examples/workers.ts. | | Deno | ✅ | | | Bun | ✅ | | | Browser | ❌ | CORS blocks direct calls to news.google.com. |

License

MIT.