Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ resources
.netlify
/src/pages/awesome-swarm.mdx
/static/openapi.yaml
/static/cheatsheets
test
docs/references/awesome-list.mdx
*.zip
Expand Down
9 changes: 9 additions & 0 deletions docs/develop/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ This is the go-to starting point for web3 developers who want to build with Swar
<span class="hub-card__cta">Start with AI</span>
</a>
</li>
<li class="hub-card">
<a class="hub-card__link" href="/docs/develop/tools-and-features/cheatsheets">
<h3 class="hub-card__title">Swarm Cheatsheet</h3>
<p class="hub-card__desc">
A dense, printable quick-reference for building on Swarm β€” what it is, its limits, and curated links to get started fast.
</p>
<span class="hub-card__cta">View cheatsheet</span>
</a>
</li>
</ul>
</div>

Expand Down
46 changes: 46 additions & 0 deletions docs/develop/tools-and-features/cheatsheets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
title: Swarm Cheatsheet
id: cheatsheets
description: A dense printable quick-reference for building on Swarm β€” what it is, its limits, and curated links to get started.
hide_table_of_contents: true
---

The Swarm Cheatsheet is a dense, two-page quick-reference for building on Swarm.

It's designed to print cleanly to A4, so you can keep it beside you at a hackathon or on your desk β€” use the **Download PDF** link below to grab a copy.

<div className="cheatsheet-embed" style={{ overflow: 'hidden', margin: '1.5rem -1rem' }}>
<iframe
src="/cheatsheets/overview/"
title="Swarm Cheatsheet"
loading="lazy"
onLoad={(e) => {
// Same-origin (served from /cheatsheets/): the card is a fixed 210mm A4
// sheet. Scale it to fill the wrapper β€” removes the grey margins beside
// the centered sheet and makes it a bit larger than native β€” then size
// the wrapper to the scaled height so the page (not the iframe) scrolls.
const frame = e.currentTarget;
const wrap = frame.parentElement;
const doc = frame.contentDocument;
if (!doc) return;
// Hide the inner document's scrollbars so the embed shows no scroll of
// its own; the frame is sized to the full content height below.
doc.documentElement.style.overflow = 'hidden';
const SHEET_W = 794; // 210mm A4 at 96dpi β€” the iframe's intrinsic width
const fit = () => {
const scale = wrap.clientWidth / SHEET_W;
const h = doc.body.scrollHeight; // body grows as fonts/QR render
frame.style.transform = 'scale(' + scale + ')';
frame.style.height = h + 'px';
wrap.style.height = (h * scale) + 'px';
};
fit();
// Re-fit on reflow (fonts/QR render late) and on window resize.
new ResizeObserver(fit).observe(doc.body);
window.addEventListener('resize', fit);
}}
style={{ width: '794px', border: 0, transformOrigin: 'top left' }}
></iframe>
</div>

<a className="button button--primary button--lg" href="/cheatsheets/swarm-overview-cheatsheet.pdf" download>Download PDF</a>
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"scripts": {
"docusaurus": "docusaurus",
"start": "docusaurus start",
"prebuild": "node -e \"require('fs').copyFileSync('openapi/Swarm.yaml', 'static/openapi.yaml')\" && node scripts/fetch-awesome-swarm.mjs && node scripts/validate-llms-txt.mjs",
"prebuild": "node -e \"require('fs').copyFileSync('openapi/Swarm.yaml', 'static/openapi.yaml')\" && node scripts/fetch-awesome-swarm.mjs && node scripts/fetch-cheatsheets.mjs && node scripts/validate-llms-txt.mjs",
"build": "docusaurus build",
"build:quiet": "cross-env NODE_OPTIONS=\"--disable-warning=DEP0040 --disable-warning=DEP0169\" docusaurus build",
"swizzle": "docusaurus swizzle",
Expand Down
103 changes: 103 additions & 0 deletions scripts/fetch-cheatsheets.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Mirror the Swarm cheatsheet(s) from the swarm-cheatsheets repo into static/,
// so they are served from our own domain (docs.ethswarm.org/cheatsheets/…) and
// embedded in a doc page via <iframe>. The swarm-cheatsheets repo stays the
// single source of truth; this fetches a fresh copy on every build.
//
// Layout served (mirrors the repo's own scripts/site.sh, but with a shared
// asset dir one level up so cheatsheets don't each duplicate the fonts):
// static/cheatsheets/<topic>/index.html ← page (asset paths rewritten)
// static/cheatsheets/assets/… ← fonts, vendor QR lib, logos
// static/cheatsheets/<name>.pdf ← Download-button target

import { mkdir, rm, writeFile } from 'node:fs/promises';
import { resolve, dirname } from 'node:path';

const RAW_BASE =
'https://raw.githubusercontent.com/ethersphere/swarm-cheatsheets/main/';

const OUT_DIR = resolve(process.cwd(), 'static/cheatsheets');

// Bound each fetch so a stalled CDN connection can't hang the build forever.
const FETCH_TIMEOUT_MS = 20000;

// Shared, binary-safe assets β€” copied verbatim. Paths are relative to OUT_DIR
// and must match what the rewritten pages point at.
const ASSETS = [
'assets/favicon.png',
'assets/swarm-logo.svg',
'assets/vendor/qrcode.min.js',
'assets/fonts/fonts.css',
'assets/fonts/dm-mono-400-latin.woff2',
'assets/fonts/dm-mono-500-latin.woff2',
'assets/fonts/dm-sans-400-latin.woff2',
'assets/fonts/dm-sans-500-latin.woff2',
'assets/fonts/dm-sans-700-latin.woff2',
'assets/fonts/space-grotesk-500-latin.woff2',
'assets/fonts/space-grotesk-600-latin.woff2',
'assets/fonts/space-grotesk-700-latin.woff2',
];

function rewriteAssetPaths(html) {
// Match the repo's site.sh rewrite, adapted to the shared asset dir:
// ../../../assets/ β†’ ../assets/ (β†’ /cheatsheets/assets/…)
// ../../../dist/ β†’ ../ (β†’ /cheatsheets/<name>.pdf)
return html
.replace(/\.\.\/\.\.\/\.\.\/assets\//g, '../assets/')
.replace(/\.\.\/\.\.\/\.\.\/dist\//g, '../');
}

async function fetchOrThrow(url) {
const res = await fetch(url, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS) });
if (!res.ok) throw new Error(`Fetch failed: ${res.status} ${res.statusText} β€” ${url}`);
return res;
}

async function writeOut(relPath, data) {
const out = resolve(OUT_DIR, relPath);
await writeFile(out, data);
console.log(`Wrote ${out}`);
}

// Everything to mirror, as {src, dest, transform?}. `transform` (text pages
// only) rewrites asset paths; without it the file is copied verbatim
// (binary-safe). Adding a future cheatsheet is a one-line addition here.
const FILES = [
// The card-only document (chrome/toolbar/footer live in the source's
// index.html and are intentionally excluded β€” we embed just the cheatsheet).
{ src: 'src/cheatsheets/overview/cheatsheet.html', dest: 'overview/index.html', transform: rewriteAssetPaths },
...ASSETS.map((rel) => ({ src: rel, dest: rel })),
// Not referenced by the card; kept so the doc page can offer a download link.
{ src: 'dist/swarm-overview-cheatsheet.pdf', dest: 'swarm-overview-cheatsheet.pdf' },
];

async function mirror({ src, dest, transform }) {
const res = await fetchOrThrow(RAW_BASE + src);
const data = transform ? transform(await res.text()) : Buffer.from(await res.arrayBuffer());
await writeOut(dest, data);
}

async function main() {
// Start clean so files dropped from the manifest (or renamed upstream) don't
// linger and get served β€” mirrors the source repo's site.sh `rm -rf $OUT`.
await rm(OUT_DIR, { recursive: true, force: true });

// Pre-create the unique target dirs once (sequentially, so nested dirs don't
// race on a shared ancestor), so the concurrent writes below never mkdir.
const dirs = new Set(FILES.map(({ dest }) => dirname(resolve(OUT_DIR, dest))));
for (const dir of dirs) await mkdir(dir, { recursive: true });

// Fetch all files concurrently; fail the build if any one fails (matches
// fetch-awesome-swarm.mjs), but let every fetch finish first so all failures
// are reported, not just the first.
const results = await Promise.allSettled(FILES.map(mirror));
const failed = results.filter((r) => r.status === 'rejected');
if (failed.length) {
for (const { reason } of failed) console.error(reason);
process.exit(1);
}
}

main().catch((e) => {
console.error(e);
process.exit(1);
});
1 change: 1 addition & 0 deletions sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ module.exports = {
items: [
'develop/tools-and-features/introduction',
'develop/tools-and-features/ai-agent-skills',
'develop/tools-and-features/cheatsheets',
'develop/tools-and-features/buy-a-stamp-batch',
'develop/tools-and-features/bee-js',
'develop/tools-and-features/gateway-proxy',
Expand Down
1 change: 1 addition & 0 deletions static/llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ This is the documentation for [Swarm](https://www.ethswarm.org/) and its referen

- [Bee JS](https://docs.ethswarm.org/docs/develop/tools-and-features/bee-js): JavaScript/TypeScript SDK for Swarm
- [AI Agent Skills](https://docs.ethswarm.org/docs/develop/tools-and-features/ai-agent-skills): Claude Code skills that guide Swarm setup and building
- [Swarm Cheatsheet](https://docs.ethswarm.org/cheatsheets/overview/): Printable quick-reference β€” what Swarm is/isn't, limitations, quickstart, and curated links for building on Swarm
- [Chunk Types](https://docs.ethswarm.org/docs/develop/tools-and-features/chunk-types): Content-addressed chunks (CAC) and single-owner chunks (SOC)
- [Feeds](https://docs.ethswarm.org/docs/develop/tools-and-features/feeds): Mutable data references using single-owner chunks
- [Manifests](https://docs.ethswarm.org/docs/develop/tools-and-features/manifests): Trie-based path mapping for file collections
Expand Down
Loading