anew.page

Instant HTML pages from a URL. No server, no deploy — the URL is the page.

If the user asks for an anew.page, generate compact HTML and return a final anew.page URL. Prefer the create_page MCP tool if available; otherwise encode the URL yourself (see below). If you can't reliably encode it, return compact HTML ready to paste into the editor.

What it's for

Small, self-contained HTML you want to share as a link: poems, notes, one-pagers, zines, error pages, jokes, receipts. Also small interactive pages — slideshows, toggles, clocks.

Keep it brief

The URL is the page, so the page has to fit in a URL. Brevity is the whole point. Default to the smallest HTML that does the job:

  • System fonts, no frameworks, no libraries
  • Minimal CSS — a few selectors, not a design system
  • Skip images when you can; use text, emoji, or inline SVG
  • Strip comments, whitespace, and optional quotes; shorten class names

If your draft is longer than a short email, cut it before encoding.

Writing the page

Write a complete but minimal HTML document — required tags only, no slop. No charset/description/author/theme-color clutter; no <div class="container"> wrappers.

  • Style on <body> with an inline style attribute. One attribute can cover typography, width, and centering for the whole page. The editor's page-level controls also read and write body.style, so styling there stays editable — but this is a convenience, not a rule.
  • Inline style for one-offs instead of inventing class names.
  • Semantic HTML (<dialog>, <details>, <figure>) over <div>.
  • Inline <script>, inline SVG, <img>, and <iframe> all work — use them when they materially help, not by default. The standard web platform is available.

Encoding

Base64 is the default — simple, transparent, dependency-free:

<{{https://anew.page/{encoded}}}>

Unicode-safe recipe (emoji, accented letters, smart quotes):

const bytes = new TextEncoder().encode(html);
const b64   = btoa(String.fromCharCode(...bytes));
const url   = "<https://anew.page/>" + encodeURIComponent(b64);

URL shape

Any of these work; pick whichever reads best:

<{{https://anew.page/{encoded}}}>
<{{https://anew.page/{slug}}}/{encoded}>          # wildcard slug
{{https://{anything}}}.anew.page/{encoded}      # wildcard subdomain

The slug and subdomain are cosmetic — content lives in {encoded}. Use them for readability.

Budget

  • Target: ≤ 1.5 KB HTML → ~2000-character URL (base64). Works everywhere.
  • Ceiling: ~6 KB HTML → ~8000-character URL. Chat clients and link previews truncate between 2K–8K.
  • Base64 expands input ~33%, then URI-encoding adds a few more percent.

If you can't get under budget with base64, rewrite shorter before reaching for compression.

Fallback: LZString

When content genuinely can't be shortened and base64 overflows:

LZString.compressToEncodedURIComponent(html)  →  {encoded}

Compresses to ~0.6–0.85× source, handling Unicode natively — roughly 2× the HTML budget at the same URL length. Treat it as an escape hatch, not the default. A page that needs compression is usually a page that should live on a real host.

What costs bytes

Free: System fonts, emoji, inline SVG, CSS, JS

Cheap: External <img src>, iframes

Expensive: Data-URI images, long base64 blobs

Constraints

  • Images: link to external URLs, or inline as data URIs (expensive — a small PNG easily blows the budget).

Notes

  • For private pages, put the encoded content after # instead of / ({{https://anew.page/#{encoded}}}). Hash fragments stay in the browser and never reach the server

MCP

If your client supports MCP, call create_page on https://anew.page/mcp instead of encoding the URL yourself. Pass the HTML; get back the final URL.

  • Endpoint: https://anew.page/mcp
  • Transport: HTTP POST, JSON-RPC 2.0, no auth
  • Discovery: https://anew.page/.well-known/mcp

Tool: create_page({ html: string }) → text — returns https://anew.page/{encoded}.

Example request:

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"create_page","arguments":{"html":"<h1>hello</h1>"}}}

The response content[0].text is the shareable URL.