Public
Reformats CourtListener opinions for better read later parsing
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.

courtlistener-reflow

Reformats CourtListener opinions for better read-later parsing.

Problem

CourtListener serves opinion text wrapped in a single <pre class="inline"> block, with hard line-wraps and page-break characters baked into the source. On courtlistener.com this is styled to look normal, but read-later tools like Readwise Reader and GoodLinks strip site CSS and fall back to default <pre> rendering — a fixed-width, non-wrapping code block.

What this does

Given a CourtListener opinion URL, this val:

  1. Extracts the cluster ID from the URL.
  2. Looks up the cluster and its lead opinion via the CourtListener REST v4 API.
  3. Reflows the opinion's html_with_citations field: strips page-break artifacts, joins hard-wrapped lines back into paragraphs, and re-wraps everything in <p> tags.
  4. Returns a clean, minimally-styled HTML page that read-later tools parse normally.

Setup

  1. Get a free CourtListener API token from your CourtListener profile.
  2. In this val's settings, add an environment variable/secret named COURTLISTENER_TOKEN with that value.
  3. Save. Val Town deploys automatically — no separate deploy step.

Usage

https://joeross-courtlistenerreflow.web.val.run/?url=<courtlistener-opinion-url>

url accepts either a full opinion URL or a bare cluster ID.

Bookmarklet

From any CourtListener opinion page, run:

javascript:location.href='https://joeross-courtlistenerreflow.web.val.run/?url='+encodeURIComponent(location.href)

This redirects to the cleaned version, which can then be saved to Readwise Reader or GoodLinks as usual.

Notes / known limitations

  • Only the lead opinion (sub_opinions[0]) is fetched. Concurrences and dissents are not included.
  • Page-break stripping assumes a docket-number-then-page-number pattern (e.g. A-2182-24 followed by a page number before a form feed). Courts with different pagination formatting may leak stray page numbers into the text.
  • CourtListener's free-tier API rate limit is 5 requests/minute, 50/hour, 125/day. Fine for one-off bookmarklet use; a constraint if wired into bulk/RSS processing.

Credits

Built with Claude.