30817:archiving-websites-on-nostr
Archiving Websites on Nostr
- signed by
- npub175rna...gsef5g
- published
- 2025-06-05
- event
- 2db5bb0f02...828c
NIP-XX
Archiving Websites on Nostr
draft
Abstract
This NIP defines a mechanism for archiving websites on Nostr by storing website assets (HTML, CSS, JavaScript, images, etc.) as events on Nostr relays. It enables decentralized, tamper-resistant storage and retrieval of web content, eliminating reliance on centralized servers. Clients can reconstruct archived websites by fetching events from relays, ensuring censorship resistance and fault tolerance.
Motivation
Centralized web hosting is vulnerable to censorship, server failures, and data loss. Archiving websites on Nostr allows content to be preserved across multiple relays, making it resilient to blocking or deletion. This NIP enables users to archive static websites, snapshots of dynamic pages, or entire sites, with verifiable integrity via public-key signatures. It supports use cases like preserving historical web content, sharing immutable site versions, and hosting decentralized web applications.
Definitions
- Website Asset: A single file (e.g., HTML, CSS, JS, image) that constitutes part of a website.
- Archived Website: A collection of assets stored as Nostr events, linked via event IDs to reconstruct the site.
- Relay: A Nostr server that stores and serves events containing website assets.
- Client: A Nostr-compatible application that publishes or retrieves archived website assets.
Event Kinds
This NIP introduces the following event kinds for archiving website assets:
- Kind 34200: Website HTML content.
- Kind 34201: Website CSS content.
- Kind 34202: Website JavaScript content.
- Kind 34203: Website image content (e.g., PNG, JPEG).
- Kind 34204: Website metadata event (describes the archived website and links assets).
Event Structure
Asset Events (Kinds 34200–34203)
These events store the content of individual website assets.
content: The raw content of the asset (e.g., HTML markup, CSS rules, JS code, or base64-encoded image data).tags:["x", "<SHA-256 hash of content>"]: The SHA-256 hash of the content for integrity verification.["m", "<MIME type>"]: The MIME type of the asset (e.g.,text/html,text/css,application/javascript,image/png). Must be lowercase.["t", "<asset type>"]: The type of asset (html,css,js,image).["r", "<website identifier>"]: A unique identifier for the website, typically the root event ID of the metadata event (kind 34204).
pubkey: The public key of the user archiving the asset.sig: The signature verifying the event's authenticity.
Example (HTML Asset Event):
{
"kind": 34200,
"content": "<!DOCTYPE html><html><head><link rel=\"stylesheet\" href=\"066b7ca0b167f0adad5c6d619ab1177050423e3979e83b8dfa069992533bdcf5\"></head><body><h1>Hello, Nostr!</h1></body></html>",
"tags": [
["x", "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2"],
["m", "text/html"],
["t", "html"],
["r", "f7d8e9a2-4b3c-4e5a-9f6b-3c8d7f1e2a3d"]
],
"pubkey": "27866e9d854c78ae625b867eefdfa9580434bc3e675be08d2acb526610d96fbe",
"created_at": 1738794235,
"id": "e8e616e0-d894-4936-a3f5-391682ee794c",
"sig": "..."
}
Metadata Event (Kind 34204)
This event describes the archived website and links all associated assets.
content: A JSON object containing:title: The title of the website.description: A brief description of the archived content.url: The original URL of the website (if applicable).archived_at: The timestamp of archiving (Unix timestamp).
tags:["e", "<event ID>", "<asset type>"]: References to asset events (e.g., HTML, CSS, JS, image).<asset type>ishtml,css,js, orimage.["d", "<website identifier>"]: A unique identifier for the website (same as used inrtags of asset events).
pubkey: The public key of the archiver.sig: The signature verifying the event's authenticity.
Example (Metadata Event):
{
"kind": 34204,
"content": "{\"title\":\"Example Site\",\"description\":\"A simple archived website on Nostr\",\"url\":\"https://example.com\",\"archived_at\":1738794235}",
"tags": [
["e", "e8e616e0-d894-4936-a3f5-391682ee794c", "html"],
["e", "066b7ca0b167f0adad5c6d619ab1177050423e3979e83b8dfa069992533bdcf5", "css"],
["e", "b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3", "js"],
["e", "c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4", "image"],
["d", "f7d8e9a2-4b3c-4e5a-9f6b-3c8d7f1e2a3d"]
],
"pubkey": "27866e9d854c78ae625b867eefdfa9580434bc3e675be08d2acb526610d96fbe",
"created_at": 1738794235,
"id": "f7d8e9a2-4b3c-4e5a-9f6b-3c8d7f1e2a3d",
"sig": "..."
}
Client Behavior
Archiving a Website
- Collect Assets: The client gathers all assets (HTML, CSS, JS, images) from the website.
- Replace Internal Links: Replace
hrefandsrcattributes with the event IDs of corresponding asset events. - Publish Asset Events: For each asset, create an event (kinds 34200–34203) with the asset content, MIME type, SHA-256 hash, and website identifier.
- Publish Metadata Event: Create a kind 34204 event linking all asset events via
etags and describing the website. - Send to Relays: Publish all events to one or more Nostr relays.
Retrieving an Archived Website
- Query Metadata Event: The client queries relays for the kind 34204 event using the website identifier (via
dtag). - Fetch Asset Events: Using the
etags in the metadata event, fetch the referenced asset events (kinds 34200–34203). - Verify Integrity: Check the SHA-256 hash in the
xtag against the content to ensure it has not been tampered with. - Render Website: Reconstruct the website by rendering the HTML, applying CSS, executing JS, and displaying images.
- Handle Missing Assets: If an asset is unavailable on one relay, query other relays or fallback to alternative sources (e.g., IPFS, if specified in tags).
Relay Behavior
- Store Events: Relays store kind 34200–34204 events as they would any other Nostr event.
- Query Support: Relays must support filtering by
kind,dtag (website identifier), andetags (event references). - Optional Pruning: Relays may prune older events based on their policies, but archiving relays should prioritize long-term storage.
- Content-Type Headers: When serving asset events via HTTP (e.g.,
/e/<event_id>), relays should set theContent-Typeheader based on themtag (e.g.,text/html,image/png).
Backwards Compatibility
- Clients and relays that do not implement this NIP will ignore kinds 34200–34204, ensuring no disruption to existing Nostr functionality.
- The use of standard tags (
e,d,x,m) aligns with existing Nostr conventions, making implementation straightforward.
Security Considerations
- Tamper Resistance: The SHA-256 hash in the
xtag ensures content integrity. Clients must verify hashes before rendering. - Signature Verification: Clients must validate event signatures to ensure authenticity.
- Spam Mitigation: Relays may implement rate-limiting or authentication to prevent abuse, but this is outside the scope of this NIP.
- Privacy: Asset content is public by default. For private archives, clients should encrypt content using NIP-04 or NIP-44 before publishing.
Extensibility
- Additional Asset Types: New kinds can be defined for other asset types (e.g., fonts, videos) in future NIPs.
- Alternative Storage: Tags can include references to external storage (e.g., IPFS, torrent) for redundancy.
- Dynamic Content: Future NIPs could extend this to archive dynamic content by snapshotting server responses.
Implementation Notes
- Clients should provide tools to crawl websites, generate events, and publish them to relays.
- Relays supporting this NIP should advertise support for kinds 34200–34204 to help clients discover compatible infrastructure.
- Example implementation: A browser extension could archive a webpage by generating events and publishing them to a user-specified relay.
References
Cited links
github.com
nips/94.md at master · nostr-protocol/nips
Nostr Implementation Possibilities. Contribute to nostr-protocol/nips development by creating an account on GitHub.
github.com
NIP-XX Decentralized Web Hosting on Nostr · Issue #742 · nostr-protocol/nips
Decentralized Web Hosting on Nostr By recording HTML, CSS, and JS on the Nostr relay, it becomes possible to create a decentralized web hosting solution that eliminates the need for centralized ser...
nostr.how
The Nostr Protocol
This is a high-level overview of the Nostr protocol with details on Event types and how Nostr Implementation Possibilities (NIPs) work.
nips.nostr.com
NIP 7 - `window.nostr` capability for web browsers — Nostr Implementation Possibilities
The window.nostr object may be made available by web browsers or extensions and websites or web-apps may make use of it after checking its availability.…
github.com
nips/01.md at master · nostr-protocol/nips
Nostr Implementation Possibilities. Contribute to nostr-protocol/nips development by creating an account on GitHub.
Discussion
Connect a key to comment.