Migrating from ReadMe
A ReadMe site moves to Writedocs with one command. It reads the published site - no ReadMe account or API key needed - and writes a complete project: every page, the API reference, the recipes, the landing page, the images ReadMe hosts, and writedocs.json.
writedocs convert --readme docs.example.com my-docsGive it the site’s address (its custom domain, or your-project.readme.io) and a folder to write into - an empty one, or one that doesn’t exist yet. It lists what couldn’t be carried over as-is, and then checks every page the way writedocs validate does:
✓ Converted https://docs.example.com into my-docs: 144 pages, 75 of them API operations, 5 recipes, 87 images
ℹ 1 thing couldn't be carried over as-is:
docs/payouts, docs/transfers
A recipe card (TutorialTile) links to a recipe that isn't on the site any more - the card is left out.
✓ Checked 144 pages: 0 errors, 0 warningsThen preview it with writedocs dev and check its links with writedocs broken-links.
What you get
- writedocs.json
- index.mdx
- docs
- getting-started.mdx
- reference
- create-user.mdx
- recipes
- first-payment.mdx
- openapi
- my-api.json
- images
- 0392eac-diagram.png
- readme-html.css
Every page keeps its address: /docs/getting-started, /reference/create-user and /recipes/first-payment are the same pages on the new site, so links from elsewhere and search results keep working.
| File or folder | What it holds |
|---|---|
writedocs.json | The site’s name, domain, colors, logo, favicon and navigation. |
index.mdx | The landing page, when the site has one. |
docs/ | The guides. |
reference/ | The API reference: an endpoint’s page, and any other page of that section. |
recipes/ | The recipes. |
openapi/ | The API definition the endpoint pages show, one file per API. |
images/ | Every image ReadMe hosted - in pages, the logo and the favicon. Images hosted anywhere else stay where they are. |
readme-html.css | Written when pages have hand-written HTML (see HTML). |
What it converts
| On ReadMe | In Writedocs |
|---|---|
| The Guides, API Reference and Recipes sections | Tabs, named as the site names them. |
| A sidebar category | A group. |
| A page with pages under it | A group whose label opens that page. |
| An API tag (the heading above its endpoints) | A group, and a redirect from its old address to its first endpoint, as ReadMe had. |
| A link in the sidebar | An external link in the sidebar. |
| A hidden page | A page with hidden: true - built, but out of the sidebar. |
| An endpoint page | A page that shows its operation from the API definition - see API reference. |
| A page’s excerpt | Its description. |
| The landing page | index.mdx, a custom page. |
| Brand color, logo, favicon, light or dark default | styles.colors.primary, styles.logo, styles.favicon, styles.appearance. |
| The custom domain | domain. |
| Redirects | redirects. |
Page content
| On ReadMe | In Writedocs |
|---|---|
Callouts - <Callout> and > 📘 Title blockquotes | A Callout with that title. 📘 is info, 👍 check, 🚧 warning, ❗️ danger. |
<Cards> and <Card> | A card group and cards. Font Awesome icon names lose their fa- prefix. |
<Image> | A Markdown image, or an Image when it has a width or a caption. |
| Code blocks written one after another | A code group, one tab per block. curl, node and sh are highlighted as Bash, JavaScript and Bash. |
<TutorialTile> | A card to the recipe. |
<Accordion>, <Tabs> | Unchanged - Writedocs has them: Accordion, Tabs. |
<Embed> | A card linking to what it embedded. |
<Anchor> | A link. |
Glossary terms - <<glossary:term>> | A Hint with the term’s definition. |
Variables - <<name>> | [[name]] - see Variables. Add each one’s value to writedocs.json’s variables. |
<HTMLBlock> | The same HTML - see HTML. |
Links - doc:, ref:, recipe:, and links to the site itself | Links to the page’s path. A link with a version (/v1.0/docs/...) loses it. |
Placeholders like <YOUR_API_KEY> in the text | Shown as written. |
API reference
The API definition is downloaded whole and written to openapi/, one file per API. Each endpoint page names its operation in the definition:
---
title: Create user
openapi: "openapi/my-api.json POST /users"
---So the page shows the operation - its parameters, responses and an API playground - with its old title, address and place in the sidebar. See OpenAPI. When the whole definition can’t be downloaded, it’s rebuilt from the endpoint pages, and the list says so.
Recipes
A recipe becomes a page with its code pinned in the right-hand column - see RequestExample and ResponseExample - and its steps as Steps. Each step shows the lines of the code it’s about, in every language.
HTML
Hand-written HTML - an <HTMLBlock>, or a landing page built in HTML - is converted to the same HTML, styles and all, written so that a page can hold it: class becomes className, for example. Each block sits in a <div className="readme-html">.
That HTML sets its own colors, usually for a light page only. readme-html.css lets the headings inside it inherit those colors, so they stay readable in dark mode too. The blocks’ own backgrounds don’t change with the theme: to make one follow it, replace it with components, or style it with [data-theme="dark"] - see Custom CSS and scripts.
After converting
- Set your colors for dark mode. A ReadMe site is often light only. When its brand color is too dark to read on a dark page,
styles.colors.dark.primaryis set to a lighter version of it, and the list says so - change it if your brand has its own. - Fix the broken links.
writedocs broken-linkslists every link that doesn’t lead anywhere, with a suggestion. Some were broken on ReadMe too: a page that was renamed, a heading that changed. - Look at the pages with HTML. Check them in light and dark mode.
Not converted
- Other versions. Only the version the site opens on is converted.
- The changelog, custom pages and discussions. Add changelog entries as pages - the Update component suits them.
- Custom CSS and JavaScript from the project’s appearance settings: ReadMe’s class names have no equivalent. The list mentions them.
- ReadMe’s older
[block:...]syntax. A page still written in it is listed, and each block is shown as a code block to rewrite. - Sites that need a login. The site has to be public.
- Redirects with a pattern (
/old/*). Writedocs redirects match one exact path; these are listed. - SEO titles set apart from the page title. The page’s title is used, and the list names each page.