# Consensys docs guide
> Official documentation for this Consensys developer product.
This file contains all documentation content in a single document following the llmstxt.org standard.
## Configure agent readiness
AI agents, LLM tools, and coding assistants increasingly read documentation directly to answer
developer questions.
This page explains what the template pre-configures for you and what you must customize before
publishing.
## What's already configured
The following features ship ready to use.
You don't need to enable them, but you should understand what they do.
### `llms.txt` and `llms-full.txt` generation
The `docusaurus-plugin-llms` plugin generates two files at build time:
- `/llms.txt` — a structured index of your documentation pages, following the
[llms.txt standard](https://llmstxt.org/).
AI agents use this to discover and navigate your site efficiently.
- `/llms-full.txt` — the full documentation corpus concatenated into a single Markdown file,
suitable for use as a context document in LLM prompts.
The plugin is registered in `docusaurus.config.js`.
See [Customize the LLM index](#customize-the-llm-index) for required setup steps.
### Markdown at `.md` URLs
The `scripts/copy-md-to-build.js` post-build script copies every source `.md` file into the build
output.
This means an agent can append `.md` to any documentation URL and receive the raw Markdown source
(for example, `https://your-site.example.com/get-started/install.md`).
The script also prepends a discovery directive to each file pointing agents to `/llms.txt`.
### Copy page button
The `docusaurus-plugin-copy-page-button` package renders a button in the breadcrumb row of every
documentation page.
Readers can use it to copy the page as Markdown, open the content in ChatGPT, Claude, or Gemini,
or view the raw Markdown source.
The button is positioned via the swizzled `src/theme/DocItem/Layout` component.
No configuration is needed.
### HTTP headers and content negotiation
`vercel.json` sets:
- A `Link` response header on `/` advertising `/sitemap.xml`, `/llms.txt`, and `/llms-full.txt`
to crawlers and agents.
- `Content-Type: text/markdown` on any URL ending in `.md`.
- Server-side rewrites that map requests with `Accept: text/markdown` to the corresponding `.md`
file, enabling HTTP content negotiation.
## Required customization
The following items ship with placeholder values.
Update them before your first production build.
### Customize the LLM index
Open `docusaurus.config.js` and update the `docusaurus-plugin-llms` options:
```js
[
"docusaurus-plugin-llms",
{
// highlight-start
title: "Your product name documentation",
description:
"One or two sentences describing what your product does and what the docs cover.",
// highlight-end
docsDir: "docs",
generateLLMsTxt: true,
generateLLMsFullTxt: true,
excludeImports: true,
removeDuplicateHeadings: true,
logLevel: process.env.CI ? "quiet" : "normal",
ignoreFiles: ["assets/**", "img/**"],
},
],
```
If your docs directory has a meaningful top-level structure (for example, separate areas for
different products or audiences), add an `includeOrder` array to control the order of sections
in `llms-full.txt`:
```js
includeOrder: [
"get-started/**/*",
"concepts/**/*",
"how-to/**/*",
"reference/**/*",
],
```
### Update `static/robots.txt`
Replace the placeholder `Sitemap:` URL with your deployed site's sitemap URL:
```text
Sitemap: https://your-product.example.com/sitemap.xml
```
The rest of the file — AI crawler permissions and `Content-Signal` declarations — is already
configured to allow indexing and AI use and doesn't need to change for most sites.
If your documentation is internal-only or not licensed for AI training, remove or adjust the
`ai-train=yes` signal and the individual `User-agent` allow rules before publishing.
### Set `SITE_URL` for the Markdown build script
The `scripts/copy-md-to-build.js` script prepends a discovery directive to every raw Markdown
file pointing agents to your site's `/llms.txt`.
Set the `SITE_URL` environment variable in your build environment, or update the constant in the
script:
```js
const SITE_URL = process.env.SITE_URL || "https://your-product.example.com";
```
## AI coding assistant setup
The template ships with Cursor rules and skills that help AI coding assistants produce
documentation that meets your team's standards.
Customize these files so the assistant understands your product's specific conventions.
### Update `.cursor/rules/terminology.mdc`
Add your product-specific terms to the table in `.cursor/rules/terminology.mdc`.
This is the most important rule file to customize — without it, an AI assistant may use
inconsistent capitalization or spelling for your product name and key concepts.
Follow the existing table format:
```markdown
| Required term | Do not use |
|---------------|-----------------------|
| YourProduct | yourproduct, YOURPRODUCT |
| API key | api key, API Key |
```
### Update `.cursor/rules/contributor-workflow.mdc`
Update the sidebar, redirect, and image path guidance to match your repository's actual structure.
In particular:
- If your sidebar is manually defined rather than autogenerated, describe the file and how to add
entries.
- Update the image folder path to wherever your site stores assets.
- Add any project-specific CI checks contributors need to know about.
### Review the other rule files
The remaining rule files — `editorial-voice.mdc`, `markdown-formatting.mdc`, and
`content-types.mdc` — are generic Consensys standards and usually don't need changes.
Review them once to confirm they match your team's expectations, then adjust any sections that
conflict with your product's conventions.
### Update `.cursor/skills/author-page/SKILL.md`
If your docs site covers more than one product area or uses a content structure that differs from
the standard Diataxis layout, update the **Inputs** and **Step 1** sections to reflect your
actual areas and folder conventions.
### Update `AGENTS.md`
`AGENTS.md` is the root context file read by AI coding agents when they open your repository.
Update it with:
- Your product name and a brief description.
- The correct documentation areas and their paths.
- Any critical rules specific to your product (for example, which APIs must not be invented,
which pages are generated rather than hand-edited).
A well-written `AGENTS.md` significantly improves the quality of AI-assisted contributions by
giving the agent the context it needs before it reads a single source file.
---
## Configure Google Analytics
Docusaurus supports [Google Tag Manager](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-google-tag-manager)
and [GTag](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-google-gtag)
plugins for Google Analytics.
The plugins are installed by default in this template repository.
## Set up Google Tag Manager and GTag
Join the [**#documentation**](https://consensys.slack.com/archives/C0272B5P1CY) channel on Consensys
Slack and request your Google Analytics tags.
Provide information about your project in your request.
After receiving your tags, fill those values in `docusaurus.config.js` in the highlighted lines as follows:
```js title="docusaurus.config.js" {6,13}
const config = {
plugins: [
[
"@docusaurus/plugin-google-gtag",
{
trackingID: "G-",
anonymizeIP: true,
},
],
[
"@docusaurus/plugin-google-tag-manager",
{
containerId: "GTM-",
},
],
],
};
```
---
## Configure OpenAPI docs
There are currently no plugins available to support OpenAPI in Docusaurus 3. Please refer to the solution implemented in the [Web3Signer REST API documentation](https://docs.web3signer.consensys.io/reference/api/rest).
This page will be updated when there is a plugin available from [Redocusaurus](https://redocusaurus.vercel.app/docs/) or [Palo Alto OpenAPI](https://github.com/PaloAltoNetworks/docusaurus-template-openapi-docs).
---
## Configure search
Docusaurus has [official support for Algolia](https://docusaurus.io/docs/search#using-algolia-docsearch)
as the primary method of integrating search into documentation.
Consensys has an [open source account](https://docsearch.algolia.com/docs/who-can-apply/) with
[Algolia](https://www.algolia.com/) to hold the indexes for our documentation, but it's limited to
only open-source projects (not just the docs but also the originating source code).
If your project doesn't have any source code (general guidelines or tutorials), then it satisfies
the conditions as long as the docs are open source.
This page contains instructions for configuring Algolia for both open source and closed source projects.
## For an open source codebase
Follow these steps to configure Algolia in your project:
1. Join the [**#documentation**](https://consensys.slack.com/archives/C0272B5P1CY) channel on Consensys
Slack and ask for Algolia search integration for your doc site.
Provide details of your project so we can determine whether you're eligible for the Algolia account.
2. We will get back to you with the `appId`, `apiKey` (it's ok to expose this), and your `indexName`.
Fill those three fields in `docusaurus.config.js`:
```js {7-10} title="docusaurus.config.js"
const config = {
themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
algolia: {
// The application ID provided by Algolia
appId: "NSRFPEJ4NC", # // cspell:disable-line
// Public API key: it is safe to commit it
apiKey: "cea41b975ad6c9a01408dfda6e0061d3",
indexName: "docs-template", // Ping #documentation on Slack for your index name
},
}),
};
```
3. Add the [`algolia-search-scraper`](../../.github/workflows/algolia-search-scraper.yml) to your
repository and include an environment `algolia` with secrets for `APPLICATION_ID` and `API_KEY`.
Edit the `docs` index in the file to match your repository's index in Algolia.
This workflow runs in the background and populates the index that Algolia uses to search.
## For a closed source code base
If your project doesn't satisfy the [Algolia checklist](https://docsearch.algolia.com/docs/who-can-apply/),
then you can't use Algolia for free.
You have two options to configure search:
1. Decide if your team has a [budget](https://www.algolia.com/pricing/) for integrating the paid
version of Algolia.
If you choose this option, and have obtained financial approval, then you can follow the
open source steps.
2. [Install a local search plugin](#install-local-search-plugin) and don't use Algolia.
Note the following caveats with local search:
- Search indexing is part of the build.
For large doc sites, there might be marginal performance deficits and additional size
to the bundle.
Usually, the doc site must be very large before it's even a consideration.
- Search doesn't work when running in a development environment (`npm run start`).
You must run `npm run build` and `npm run serve` to preview the local search.
### Install local search plugin
Follow these steps to configure the [`@easyops-cn/docusaurus-search-local`](https://github.com/easyops-cn/docusaurus-search-local)
local search plugin in your project:
1. In the root of your project, install the plugin:
```bash
npm i @easyops-cn/docusaurus-search-local
```
2. Remove the entire `algolia` key under `config > themeConfig` in `docusaurus.config.js`.
This is to ensure that the Algolia search bar is overridden by the plugin.
```js title="docusaurus.config.js"
// DELETE the following code
algolia: {
// The application ID provided by Algolia
appId: "NSRFPEJ4NC", # // cspell:disable-line
// Public API key: it is safe to commit it
apiKey: "cea41b975ad6c9a01408dfda6e0061d3",
indexName: "docs-template", // Ping #documentation on Slack for your index name
// Optional: see doc section below
contextualSearch: true,
// Optional: Specify domains where the navigation should occur through window.location
//instead on history.push. Useful when our Algolia config crawls multiple documentation
// sites and we want to navigate with window.location.href to them.
externalUrlRegex: "external\\.com|domain\\.com",
// Optional: Algolia search parameters
searchParameters: {},
// Optional: path for search page that enabled by default (`false` to disable it)
searchPagePath: "search",
// ... other Algolia params
},
```
3. Apply the configuration options for the local plugin under `config > themes` in `docusaurus.config.js`:
```js title="docusaurus.config.js"
themes: [
[
require.resolve("@easyops-cn/docusaurus-search-local"),
/** @type {import("@easyops-cn/docusaurus-search-local").PluginOptions} */
({
hashed: true,
docsRouteBasePath: "/",
indexBlog: false,
}),
],
],
```
:::tip
See [more plugin options](https://github.com/easyops-cn/docusaurus-search-local#theme-options) you
can use.
:::
---
## Disable automatic semantic release
By default, this template repository includes the [`semantic-release`](../../create/repo-structure.md#-releasercjs)
package to automatically create releases in GitHub once a push or pull request is merged into the
`main` branch.
You may or may not want to disable `semantic-release` for the following reasons:
:::caution Reasons to disable `semantic-release`
- You want to manually release in line with your application's release cycle and match
the application's versioning.
- Releases are not necessary at all for your docs.
In this case, you can remove it completely and only maintain version control in GitHub.
:::
:::info Reasons to not disable `semantic-release`
- Since Docusaurus handles all docs versioning, it should not normally be necessary to release
manually to match your application release cycle.
- Locking the release of the docs to the application makes it more difficult to amend
versions after the fact.
With `semantic-release`, the releases are more flexible and relies on Docusaurus versioning
for different application versions.
:::
## Disable `semantic-release`
1. Remove `semantic-release` from `package.json`:
```bash
npm uninstall @semantic-release/changelog @semantic-release/commit-analyzer \
@semantic-release/git @semantic-release/github @semantic-release/npm \
@semantic-release/release-notes-generator
```
2. Delete the `semantic-release` configuration file:
```bash
rm .releaserc.js
```
3. Set the default value for the `release.yaml` action to `false`:
```yaml title="release.yaml"
inputs:
semantic_release:
description: "whether to use semantic-release"
required: false
default: false
```
4. _(Optional)_ You can also remove the `release.yaml` workflow entirely
if you don't need it.
---
## Configure and use versioning
Docusaurus can manage multiple versions of your documentation.
See the [Docusaurus versioning documentation](https://docusaurus.io/docs/next/versioning) for
detailed context and instructions on managing versions.
The following instructions are for documentation that uses n versions that can be accessed like so:
| Path | Version | URL |
|:----------------------------------- |:------------- |:-------------------|
|versioned_docs/version-0.x/hello.md | 0.x | /0.x/hello |
|versioned_docs/version-1.0/hello.md | 1.0 (latest) | /hello |
|docs/hello.md | development | /development/hello |
:::info
Please note that unlike Read the Docs (RTD) that versions by tags on the code base, in Docusaurus,
every version in history is kept in the `versioned_docs` folder, so the onus is on you to remove
older versions when required
:::
Docusaurus nomenclature is slightly different to what we use. In docusaurus, all actual versions
are referred to by name and are sub folders in `versioned_docs`; and the next version is therefore called
`next` (the next version). In Consensys we follow the same for the `versioned_docs` but use the
term `development` instead, and this can be configured in docusaurus.config.js like so, where
the `current` version is given a `label` and `path` attribute.
```js
...
routeBasePath: "/",
path: "./docs",
includeCurrentVersion: true,
lastVersion: "1.0",
versions: {
//defaults to the ./docs folder
// using 'development' instead of 'next' as path
current: {
label: "development",
path: "development",
},
//the last stable release in the versioned_docs/version-stable
"1.0": {
label: "1.0",
},
"0.x": {
label: "0.x",
},
},
...
```
## Release a new docs version
### 1. Create a new version of the documentation
In the following steps, we'll release the `1.0` version of the documentation (`./docs`) as an example.
```bash
npm run docusaurus docs:version
```
This command:
- Copies the full `docs/` directory into a new `version-` directory in
the `versioned_docs` directory.
- Creates a new `versioned_sidebars/version--sidebars.json` file.
- Appends the new version number to the `versions.json` file.
```bash
npm run docusaurus docs:version 1.0
```
This command:
- Copies the full `docs/` directory into a new `version-1.0` directory in the `versioned_docs` directory.
- Creates a new `versioned_sidebars/version-1.0-sidebars.json` file.
- Appends the new version number to the `versions.json` file.
Your docs now have two versions:
- `1.0` at `http://localhost:3000/` for the version 1.0 docs
- `current` at `http://localhost:3000/next/` for the upcoming, unreleased docs.
### 2. Update the `docusaurus.config.js` file to re-label these paths
In `docusaurus.config.js`, under `presets` > `classic` > `docs`:
- Update the `lastVersion` to the new version number.
- Under `versions`, update the current version to the new version.
For example, when releasing version `1.0`, update the following section in the `docusaurus.config.js`
file by updating the version number:
```js
presets: [
[
"classic",
{
docs: {
sidebarPath: require.resolve("./sidebars.js"),
// Set a base path separate from default /docs
editUrl: "https://github.com/consensys/doc.teku/tree/master/",
routeBasePath: "/",
path: "./docs",
includeCurrentVersion: true,
// highlight-next-line
lastVersion: "1.0",
versions: {
//defaults to the ./docs folder
// using 'development' instead of 'next' as path
current: {
label: "development",
path: "development",
},
//the last stable release in the versioned_docs/version-1.0
// highlight-start
"1.0": {
label: "1.0",
},
// highlight-end
},
...
],
```
### 3. Update the `versions.json` file
:::info
Please remember to remove any old versions that you are not required in this file
:::
```json
[
"1.0",
"0.x"
]
```
### 4. Delete the previous doc versions (if needed)
If you have deleted a version in step 3, also delete the artifacts for that version. For example,
if deleting version `0.2` that would mean deleting the following:
1. In the `versioned_docs` directory, delete the `version-0.2` folder
2. In the `versioned_sidebars` directory, delete the `version-0.2-sidebars.json` file.
Create your pull request. You can perform a final check using the preview link generated for your PR.
### 5. Add a version dropdown (Do this once only when versioning is introduced)
To navigate seamlessly across versions, add a version dropdown by modifying `docusaurus.config.js`
as follows:
```js title="docusaurus.config.js"
module.exports = {
themeConfig: {
navbar: {
items: [
// highlight-start
{
type: "docsVersionDropdown",
},
// highlight-end
],
},
},
};
```
The docs version dropdown appears in your navbar:

## Update an existing version
You can edit versioned docs in their respective folder:
- `versioned_docs/version-1.0/hello.md` updates `http://localhost:3000/docs/hello`.
- `docs/hello.md` updates `http://localhost:3000/docs/development/hello`.
---
## Support versioned and unversioned docs
You might need part of your documentation to be versioned and another part unversioned.
Docusaurus supports multi-instance docs since the docs functionality is a plugin itself and can be
re-used multiple times.
For example, configure multiple doc instances with their own versioning systems by modifying
`docusaurus.config.js`:
```js title="docusaurus.config.js" {6-11,18-24}
module.exports = {
presets: [
[
"@docusaurus/preset-classic",
{
docs: {
// id: 'product', // omitted => default instance
path: "product",
routeBasePath: "product",
sidebarPath: require.resolve("./sidebarsProduct.js"),
// ... other options
},
},
],
],
plugins: [
[
"@docusaurus/plugin-content-docs",
{
id: "community",
path: "community",
routeBasePath: "community",
sidebarPath: require.resolve("./sidebarsCommunity.js"),
// ... other options
},
],
],
};
```
See the [Docusaurus multi-instance documentation](https://docusaurus.io/docs/docs-multi-instance#use-cases)
for detailed instructions on setting up versioned and unversioned docs.
---
## Add images
You can add [screenshots](#screenshots) and [diagrams](#diagrams) to the Consensys documentation.
Add your image to an `assets` or `images` folder within the documentation folder, and link to it in
your doc content using
[Markdown, CommonJS require, or ES imports](https://docusaurus.io/docs/markdown-features/assets#images).
You can also use HTML to center the image.
For example:
```markdown

```
```jsx
```
```jsx
```

## Screenshots
Follow the [Archbee screenshot guidelines](https://www.archbee.com/blog/screenshots-in-technical-documentation)
when adding screenshots to the Consensys docs.
You might need to re-size your screenshots to make them easy to view and to minimize the file size
for faster page loading:
- Full-width screenshots should be 600-960px wide.
- Vertical, mobile-layout screenshots should be around 360px wide.
## Diagrams
Consensys doc sites contain diagrams created using [Mermaid](https://mermaid.js.org/) and
[Figma](https://figma.com/).
Use diagrams to illustrate:
- Detailed or simplified product architecture.
- Technical processes and flows.
- Concept charts and tables.
### Mermaid
To use Mermaid diagrams in your site,
[install the Mermaid theme plugin](https://docusaurus.io/docs/markdown-features/diagrams) and use
the Mermaid diagram syntax, for example, for [flowcharts](https://mermaid.js.org/syntax/flowchart.html)
or [sequence diagrams](https://mermaid.js.org/syntax/sequenceDiagram.html).
### Figma
The following video demonstrates creating a Figma diagram for the GoQuorum documentation:
To create a Figma diagram, you must have access to the **Developer docs diagrams** template files on
Figma, and use the following general guidelines.
Refer to the [Figma help website](https://help.figma.com/hc/en-us) for more information on
getting started with Figma, Figma design elements, and more.
#### Basics
- In the **Quorum Diagrams** file on Figma, each page contains diagrams for a
different product.
- When creating a new diagram, create a new white frame in the product's page.
Add frames within the white frame for each iteration of the diagram.
- For each diagram, create a frame 756px wide using the **Global Background**
color (#F6F6F6).
- You can resize a diagram's height, but keep the width at 756px.
Anchor your elements to the frame using **Left** and **Top** [constraints](https://help.figma.com/hc/en-us/articles/360039957734-Apply-constraints-to-define-how-layers-resize)
- You can [group](https://help.figma.com/hc/en-us/articles/360039832054-Frames-and-Groups) and
[rename and organize](https://help.figma.com/hc/en-us/articles/360038663994-Name-and-organize-components)
elements.
:::tip Tips
- Hold down **Command** on Mac or **Ctrl** on Windows to
[select](https://help.figma.com/hc/en-us/articles/360040449873-Select-layers-and-objects)
elements excluding the frame.
- Hold down **Option** and drag to duplicate an element.
:::
#### Design
- Use the pre-made diagram assets as starting points.
By default, you can adjust the width of the pre-made labels, but the height is
automatically sized to the number of lines of text.
To freely customize a component, right-click on it, **detach instance**, and **remove auto layout**.
- Use the pre-defined [color styles](https://help.figma.com/hc/en-us/articles/360039820134-Manage-and-share-styles)
or black (#00000).
- Use rounded corners of radius 2 for rectangular labels and containers.
- Evenly [align](https://help.figma.com/hc/en-us/articles/360039956914-Adjust-alignment-rotation-and-position)
elements.
- Represent similar conceptual elements using similar styles.
For example, represent two nodes using a dark gradient, and represent two
external components using a light gradient.
- You can reuse existing icons from any diagram on any page.
For example, there are already icons to represent databases, dapps, keys,
locks, and logos.
:::tip
Hold down **Shift** when drawing, resizing, and rotating to create perfect
horizontal and vertical lines.
:::
#### Text
- Use font **Roboto** for all text.
- Use font sizes between 10–18.
- Use [sentence case](https://docs.microsoft.com/en-us/style-guide/capitalization)
in labels and titles.
#### Arrows and lines
- Use a thickness of 2 for arrows, lines, borders, and other strokes.
- Use **Triangle** arrow heads.
- Use straight arrows and lines, with right-angle bends if needed.
Don't use diagonal arrows and lines.
If possible, don't overlap arrows and lines.
To create additional bends in an arrow or line, **detach instance**
(if applicable), double-click the arrow or line, and click and drag the anchor points.
- Leave about 3px of space between arrow heads and the elements they point to.
Line ends without arrow heads should touch the connecting element.
:::note example

:::
See the
[Figma documentation on the Arrow Tool](https://help.figma.com/hc/en-us/articles/360040450133-Using-Shape-Tools#h_677f8eba-73c4-4987-a64b-c0226aaec392)
for more information.
#### Export your Figma diagram
1. Select the frame of your diagram.
Make sure all elements of your diagram are contained in the frame.
The name of this frame will be the name of the exported image.
2. Scroll to the bottom of the right sidebar.
In the **Export** section, choose **2x** scale (for retina screens)
and **PNG** or **SVG** file format.
3. Export the diagram to the image folder of the documentation site
(for example, `doc.goquorum/docs/assets`).
See [Figma's guide to exports](https://help.figma.com/hc/en-us/articles/360040028114-Guide-to-exports-in-Figma)
for more information.
---
## Format Markdown
Guidelines for formatting Markdown help writers and reviewers navigate the documentation source code
and review changes.
They also ensure that Markdown features render properly on the doc site.
Refer to the following guidelines when formatting Markdown in Consensys docs.
:::tip note
The Markdown syntax for [admonitions](#admonitions) and [tabs](#tabs) is specific to Docusaurus.
See the [Docusaurus Markdown documentation](https://docusaurus.io/docs/markdown-features/) for more
information on using Markdown features specific to Docusaurus.
:::
## File names
The name of each documentation folder and Markdown file must contain only lowercase letters and
dashes (`-`) to represent spaces.
Use simple file names that match the page titles and that make sense with the entire file path.
For example:
```text
how-to/
├─ get-started.md
├─ manage-keys.md
├─ request-permissions.md
├─ troubleshoot.md
concepts/
├─ architecture.md
├─ lifecycle.md
├─ execution-environment.md
...
```
## Metadata
You can configure metadata for each doc page using [Markdown front
matter](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-docs#markdown-front-matter)
at the top of the page.
For example:
```markdown
---
title: Use MetaMask SDK with React
sidebar_label: React
sidebar_position: 2
description: Import MetaMask SDK into your React dapp.
max_toc_heading_level: 3
---
```
You should provide at least a clear description for each page using front matter.
## Column limit
Each Markdown line should be (roughly) [limited to 100 columns
long](https://google.github.io/styleguide/javaguide.html#s4.4-column-limit) to be readable on any editor.
For example:
```markdown
In this example, this first sentence exceeds 100 characters, so we recommend wrapping it into
multiple lines.
One line break displays as a space, so this Markdown renders as one paragraph without line breaks.
We also recommend starting each new sentence on a new line, even if the previous line didn't reach
100 columns, for easy reviewing.
You can set a [vertical ruler](https://dev.to/brad_beggs/vs-code-vertical-rulers-for-prettier-code-3gp3)
in your text editor as a heuristic.
```
In this example, this first sentence exceeds 100 characters, so we recommend wrapping it into
multiple lines.
One line break displays as a space, so this Markdown renders as one paragraph without line breaks.
We also recommend starting each new sentence on a new line, even if the previous line didn't reach
100 columns, for easy reviewing.
You can set a [vertical ruler](https://dev.to/brad_beggs/vs-code-vertical-rulers-for-prettier-code-3gp3)
in your text editor as a heuristic.
## Tables
Format tables to be readable in the source code.
Add an appropriate number of spaces to align the columns in the source code.
For example, do this:
```markdown
| Syntax | Description |
|-----------|-------------|
| Name | Title |
| Paragraph | Text |
```
Not this:
```markdown
| Syntax | Description |
|--|--|
| Name | Title |
| Paragraph | Text |
```
You can quickly format tables using [Markdown Table Formatter](http://markdowntable.com/) or
create tables from scratch using [Tables Generator](https://www.tablesgenerator.com/markdown_tables).
Some editors also have settings or plugins to auto-format Markdown tables.
## Admonitions
Use [admonitions](https://docusaurus.io/docs/markdown-features/admonitions) to include side content
or highlight important content.
For example:
```markdown
:::caution important
`eth_sign` is deprecated.
:::
:::note
MetaMask supports signing transactions using Trezor and Ledger hardware wallets.
These wallets only support signing data using `personal_sign`.
If you can't log in to a dapp when using a Ledger or Trezor, the dapp might be requesting you to
sign data using an unsupported method, in which case we recommend using your standard MetaMask account.
:::
```
:::caution important
`eth_sign` is deprecated.
:::
:::note
MetaMask supports signing transactions using Trezor and Ledger hardware wallets.
These wallets only support signing data using `personal_sign`.
If you can't log in to a dapp when using a Ledger or Trezor, the dapp might be requesting you to
sign data using an unsupported method, in which case we recommend using your standard MetaMask account.
:::
## Links
Use relative file paths for [Markdown links](https://docusaurus.io/docs/markdown-features/links) where possible. For example:
```md
You can enable users to create a [MetaMask smart account](../../concepts/smart-accounts.md) directly in your dapp.
```
## Code samples
Use [code blocks](https://docusaurus.io/docs/markdown-features/code-blocks) to present code samples.
A basic code block uses triple back ticks (`` ` ``) and the language name to enable
[syntax highlighting](https://docusaurus.io/docs/markdown-features/code-blocks#syntax-highlighting).
For example:
````markdown
```javascript
if (typeof window.ethereum !== "undefined") {
console.log("MetaMask is installed!");
}
```
````
```javascript
if (typeof window.ethereum !== "undefined") {
console.log("MetaMask is installed!");
}
```
### Code sample style guide
Make sure to provide developer-friendly code samples.
The following are some rules used throughout the Consensys docs:
- Use double quotes (`"`) instead of single quotes (`'`).
- Indent lines using two spaces instead of four.
- Write code samples that can be easily copied and pasted, and work as expected.
- Follow the style guide of the programming language used in the code sample.
:::info example
❌ *To start Teku, run the following command:*
```bash
// Set --ee-endpoint to the URL of your execution engine and
// --ee-jwt-secret-file to the path to your JWT secret file.
user@mycomputer Develop % teku --ee-endpoint=http://localhost:8550 --ee-jwt-secret-file=my-jwt-secret.hex
```
✅ *To start Teku, run the following command:*
```bash
teku \
--ee-endpoint= \
--ee-jwt-secret-file= \
--metrics-enabled=true \
--rest-api-enabled=true
```
:::
See the
[Microsoft Writing Style Guide](https://learn.microsoft.com/en-us/style-guide/developer-content/code-examples)
for more guidelines for writing code examples.
## Tabs
Use [tabs](https://docusaurus.io/docs/markdown-features/tabs) to display certain content, such as
code samples in different languages.
For example:
````jsx
```html
```
```javascript
// JavaScript code block
```
```markdown
- This is an example Markdown list.
- This is **bold** and *italicized* text.
```
````
This renders as the following:
```html
```
```javascript
// JavaScript code block
```
```markdown
- This is an example Markdown list.
- This is **bold** and *italicized* text.
```
---
## Preview the docs
Use npm to preview your documentation changes locally before pushing them to your remote branch.
Make sure you have [Node.js version 20+ and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)
installed.
:::tip
If you're using Node.js with [nvm](https://github.com/nvm-sh/nvm/blob/master/README.md)
(recommended), run `nvm use` to automatically choose the right Node.js version.
:::
:::note
If you make changes to a versioned doc site (for example, [Teku](https://docs.teku.consensys.net/)),
the changes only appear in the development version of the docs.
Switch to the development version of the preview to see those changes.
:::
## Use npm
In the root of the doc project, run the following commands to start a local development server and preview
your changes:
```bash
npm install
npm start
```
:::note
If you make changes to the [redirects](../create/configure-docusaurus.md#redirects), you can preview them by
running `npm run build && npm run serve`.
:::
---
## Review contributions
To
[review a documentation pull request
(PR)](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/about-pull-request-reviews):
1. Go to the PR page.
2. Select the **Files changed** tab and read through the documentation changes.
3. View the rendered changes in the PR preview link.
4. Evaluate the changes to the best of your ability.
To approve the changes, make sure that:
- The changes are technically accurate.
- The changes improve your understanding of the subject.
- The changes make sense in the context they're in.
- You're not left with any confusion or questions about the subject of the changes.
- The changes follow the [writing style guidelines](style-guide.md) and the
[markdown guidelines](format-markdown.md).
5. In the **Files changed** tab, hover over any line you want to comment on to the right of the line
number, and select the plus sign (+).
You can also drag to select multiple lines at once.
Add your comment, or select the file symbol to make a specific suggestion.
Select **Start a review**, and repeat for any other comments or suggestions.
6. When you're done commenting, select **Finish your review** in the upper right corner, and select:
- **Comment** if you have comments or suggestions you want the PR author to consider.
- **Approve** if you think the PR is OK to merge.
- **Request changes** if you require the author to make changes.
Selecting this option requires you to approve the PR later before the author can merge it.
7. Submit your review.
---
## Run the link checker
The documentation suite uses [Linkspector](https://github.com/UmbrellaDocs/linkspector) as the link checker.
Linkspector is integrated into the continuous integration (CI) pipeline and is executed on each pull request (PR) using a GitHub action.
:::info important
The Linkspector GitHub workflow runs on all Markdown files in the repository, not only the ones you've updated.
Failures in the workflow won't prevent your PR from being merged.
:::
## Run locally
Run Linkspector locally to view issues before pushing your changes to GitHub:
1. Install Linkspector locally:
```bash
npm install -g @umbrelladocs/linkspector
```
2. Navigate into the documentation directory you want to check.
3. Run Linkspector:
```bash
linkspector check
```
## Configure the link checker
Linkspector looks for a configuration file named `.linkspector.yml` in the current directory.
If your site doesn't have this file, the local Linkspector check will use the default configuration,
and the Linkspector GitHub action will fall back to the configuration file in [`Consensys/github-actions`](https://github.com/Consensys/github-actions/blob/main/docs-link-check/config/.linkspector.yml).
You can add or update the `.linkspector.yml` file in the root of your documentation site with specific configuration options.
For example:
```yml title="doc.din/.linkspector.yml"
dirs:
- ./docs
excludedDirs:
- ./build
- ./.vercel
- ./.docusaurus
- ./node_modules
useGitIgnore: true
ignorePatterns:
- pattern: "^/img/"
- pattern: "^/static/"
- pattern: "^/llms\\.txt$"
- pattern: "^/llms-full\\.txt$"
- pattern: "^http(s)?://localhost"
- pattern: "^http(s)?://127.0.0.1"
- pattern: "^http(s)?://docs\\.eigencloud\\.xyz"
aliveStatusCodes:
- 200
- 201
- 204
- 206
```
Learn more about how to [configure Linkspector](https://github.com/UmbrellaDocs/linkspector?tab=readme-ov-file#configuration).
---
## Run the spelling and style linter
The documentation suite uses [Vale](https://vale.sh/) as the style guide and spelling linter.
Vale is integrated into the continuous integration (CI) pipeline and is executed on each
pull request (PR) using a GitHub action. You can select the **Details** link to view the logs.

:::info important
The Vale GitHub workflow runs on all Markdown files (and for some repos YAML files) in the repository, not
only the ones you've updated. However, only items related to files in your PR receive alerts.
Failures in the workflow won't prevent your PR from being merged.
You can run Vale locally to view issues directly related to your PR.
:::
## Run locally
Run Vale locally to view issues related to the Markdown files you're working on. You can run Vale using the
command line, or you can integrate it into a [supported editor](https://vale.sh/docs/integrations/guide/) to
view issues in real-time.
### Use the command line
1. [Install Vale locally](https://vale.sh/docs/vale-cli/installation/#package-managers).
1. Clone the repo containing our Vale settings:
```bash
git clone git@github.com:Consensys/github-actions.git
```
1. Override the default location of the `.vale.ini` file by setting the `VALE_CONFIG_PATH` environment
variable to the location of the file in the repo. For example, on macOS this is:
```bash
export VALE_CONFIG_PATH="/Users/{user-name}/documentation/github-actions/docs-spelling-check/.vale.ini"
```
:::note
To persist the `VALE_CONFIG_PATH` environment variable across sessions, you’ll need to add the above command to the
appropriate shell configuration file. For example, on macOS, add it to ~/.zshrc (the default shell configuration
file in recent versions of macOS).
:::
1. Run the `vale` command in your terminal with the location of your file. For example:
```bash
vale node-sync.md
```

:::note
If you pass a file that does not exist, Vale will not alert you that the file cannot be found.
You'll receive a message similar to `0 errors, 0 warnings and 0 suggestions` in the terminal.
:::
### Use the VS Code integration
You must have the [Visual Studio (VS) Code](https://code.visualstudio.com) editor installed to use this integration.
1. [Install Vale locally](https://vale.sh/docs/vale-cli/installation/#package-managers).
1. Clone the repo containing our Vale settings:
```bash
git clone git@github.com:Consensys/github-actions.git
```
1. [Install the VS Code extension](https://marketplace.visualstudio.com/items?itemName=ChrisChinchilla.vale-vscode)
1. In the settings for the Vale VS Code extension, set the location of the `.vale.ini` file, and
enable the spell check. The `.vale.ini` file is located within the `docs-spelling-check` directory in the
`github-actions` repo that you cloned onto your local.

1. Restart VS Code.
## Contribute to the spell checker
You can contribute to the spell checker by submitting a PR to the [`Consensys/github-actions` repository](https://github.com/Consensys/github-actions).
Learn more about how to [configure Vale](https://github.com/Consensys/github-actions/tree/main/docs-spelling-check#configure-vale).
---
## Style guide
Style guidelines help keep the Consensys documentation consistent, concise, and readable.
Refer to the following guides when writing, editing, or reviewing doc content:
- [**Microsoft Writing Style Guide**](https://learn.microsoft.com/en-us/style-guide/welcome/) - Refer to this guide for style, voice, grammar, and text formatting guidelines.
- [**Diátaxis framework**](https://diataxis.fr/) - Refer to this guide for information about
function-based docs.
- [**Consensys Editorial Style Guide**](https://www.notion.so/consensys/Consensys-Editorial-Style-Guide-d5b9867e85df4ae38f8bed44f61a77d5) -
Refer to this guide for spelling and usage of blockchain-related terms.
[Vale](run-vale.md) assists writers to adhere to this style.
This guide is only available to internal Consensys contributors.
The following section also highlights the top five style tips from these guides.
## Top five style tips
### 1. Organize content by function
Write and organize docs [based on function](https://diataxis.fr/):
- [How-to guides](https://diataxis.fr/how-to-guides/) provide instructions to
achieve a specific outcome.
How-to guides assume users already have some basic knowledge or understanding of the product.
- [Conceptual content](https://diataxis.fr/explanation/), or explanation, provides background
information about a feature.
Conceptual content can explain what the feature is, how it works at a high level, why it's needed,
and when and where it's used.
- [Tutorials](https://diataxis.fr/tutorials/) provide a set of end-to-end steps to
complete a project.
Tutorials are complete and reproducible.
They don't assume users have prior knowledge of the subject or required tools.
- [Reference content](https://diataxis.fr/reference/) provides technical
descriptions of APIs, command line options, and other elements of code.
Reference content is straightforward and doesn't include long explanations or guides.
### 2. Use a conversational tone
Be [simple and conversational](https://learn.microsoft.com/en-us/style-guide/brand-voice-above-all-simple-human)
in your writing:
- In general, use [active voice](https://docs.microsoft.com/en-us/style-guide/grammar/verbs#active-and-passive-voice),
[present tense](https://learn.microsoft.com/en-us/style-guide/grammar/verbs#verb-tense), and
[second person](https://learn.microsoft.com/en-us/style-guide/grammar/person) to focus on the reader.
- [Use common contractions](https://learn.microsoft.com/en-us/style-guide/word-choice/use-contractions),
such as "it’s" and "you’re," as if you're speaking to the reader.
- Be informal, but not *too* informal.
Don't use slang, figures of speech, or run-on sentences.
:::info example
❌ *If we're unable to find another library that works with the execution environment, another way
of solving the problem is by patching the dependency ourselves.
For this, `patch-package` can be leveraged.*
✅ *If you can't find another library that works with the execution environment, you can patch the
dependency yourself using `patch-package`.*
:::
### 3. Write for developers
Write for a [developer audience](https://learn.microsoft.com/en-us/style-guide/developer-content/):
- You don't need to market the product to the reader.
Understand what they're seeking to learn or do, and optimize your content to help them achieve
that fast.
- List prerequisites and suggest good practices.
For example, instruct readers to secure private keys and protect RPC endpoints in production environments.
- Write [code samples](format-markdown.md#code-sample-style-guide) that are readable, can be
copied and pasted, and work as expected.
:::info example
❌ *To start Teku, run the following command:*
```bash
// Set --ee-endpoint to the URL of your execution engine and
// --ee-jwt-secret-file to the path to your JWT secret file.
teku \
--ee-endpoint=http://localhost:8550 \
--ee-jwt-secret-file=my-jwt-secret.hex \
--metrics-enabled=true \
--rest-api-enabled=true
```
✅ *To start Teku, run the following command:*
```bash
teku \
--ee-endpoint= \
--ee-jwt-secret-file= \
--metrics-enabled=true \
--rest-api-enabled=true
```
:::
### 4. Create scannable content
Make sure readers can [effectively scan your content](https://learn.microsoft.com/en-us/style-guide/scannable-content/):
- [Get to your point fast](https://learn.microsoft.com/en-us/style-guide/top-10-tips-style-voice#get-to-the-point-fast)
and make your point clear.
- [Use short, simple sentences.](https://learn.microsoft.com/en-us/style-guide/word-choice/use-simple-words-concise-sentences)
Remove nonessential, redundant, or non-specific words and sentences.
- Break up three or more paragraphs of text with subheadings, admonitions, lists, tables, code samples,
or images.
- [Establish patterns in content.](https://learn.microsoft.com/en-us/style-guide/scannable-content/#establish-patterns-in-content)
Use consistent language across list items and page titles.
Use consistent content structure across different pages.
:::info example
❌ *Cryptographic techniques must be leveraged by the private transaction manager in order to achieve
transaction authenticity, participant authentication, and historical data preservation (that is,
through a chain of cryptographically hashed data).
Much of the cryptographic work including symmetric key generation and data encryption/decryption is
delegated to the enclave instead of the private transaction manager in order to achieve a separation
of concerns, as well as to provide performance improvements through parallelization of certain
crypto-operations.*
✅ *The private transaction manager must use cryptographic techniques to:*
- *Authenticate transactions.*
- *Authenticate participants.*
- *Preserve historical data.*
*It delegates this work to the enclave, which manages encryption and decryption in isolation.
The separation of duties between the private transaction manager and enclave improves performance
and strengthens the security of private keys.*
:::
### 5. Format text properly
Follow these rules for [formatting common text
elements](https://learn.microsoft.com/en-us/style-guide/text-formatting/):
- Use [sentence case](https://learn.microsoft.com/en-us/style-guide/capitalization) for headings,
titles, and labels.
- Use code formatting (surround text with backticks `` ` ``) for references to URLs and file names.
- Use bold text (surround text with double asterisks `**`) for references to user interface elements.
- Use [descriptive link text](https://developers.google.com/style/link-text?hl=en).
:::info example
❌ *[Click here](https://discord.gg/hyperledger) for Besu support.*
✅ *If you have questions about Besu for public networks, ask on the **#besu** channel on
[LFDT Discord](https://discord.gg/hyperledger).*
:::
---
## Submit a contribution
The Consensys documentation uses a [docs-as-code](https://www.writethedocs.org/guide/docs-as-code/)
approach, meaning documentation is created using the same tools as code.
The contribution workflow involves proposing changes to the docs by creating [forks and pull
requests (PRs)](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/getting-started/about-collaborative-development-models#fork-and-pull-model)
on the documentation GitHub repositories.
This facilitates open contributions, testing, and review.
## Steps
To contribute changes:
1. Choose the repository you'd like to contribute to.
See the [list of Consensys documentation repositories](../index.md#list-of-documentation-sites).
2. In the repository, search for an existing issue to work on, or [create a new
issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/creating-an-issue)
describing the documentation issue you'd like to address.
Make sure no one else is assigned to the issue, and assign yourself to it.
If you don't have permission to assign yourself to it, leave a comment on the issue or contact a
maintainer of that repository.
3. [Fork the repository](https://docs.github.com/en/get-started/quickstart/fork-a-repo#forking-a-repository)
to your personal account.
:::note
If you have write access to a repository, you can skip steps 3–6 and clone the
original repository instead.
:::
4. [Clone your forked repository](https://docs.github.com/en/get-started/quickstart/fork-a-repo#cloning-your-forked-repository)
to your computer.
```bash
git clone
```
5. Change directories into the cloned forked repository.
```bash
cd
```
6. [Add an upstream remote.](https://docs.github.com/en/get-started/quickstart/fork-a-repo#configuring-git-to-sync-your-fork-with-the-upstream-repository)
```bash
git remote add upstream
```
7. [Create and checkout a topic branch](https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging),
naming it appropriately.
We recommend including the issue number and a short description in the branch name (for example,
`183-doc-cli-option`), which is a reminder to fix only one issue in a PR.
```bash
git checkout -b -
```
:::tip
You can use a Git client such as [Fork](https://fork.dev/) instead of the command line.
:::
8. Open the repository in a text editor of your choice (for example, [VS Code](https://code.visualstudio.com/))
and make your documentation changes.
Make sure to [follow the style guidelines](style-guide.md) and [format your Markdown correctly](./format-markdown.md).
:::caution important
If you delete, rename, or move a documentation file, make sure to add a
[redirect](../create/configure-docusaurus.md#redirects).
:::
9. [Preview your changes locally](preview.md) to check that the changes render correctly.
10. Add and commit your changes, briefly describing your changes in the commit message.
Push your changes to the remote origin.
```bash
git add *
git commit -m ""
git push origin
```
11. On the original repository on GitHub, you’ll see a banner prompting you to create a PR with your
recent changes.
Create a PR, describing your changes in detail.
[Link the issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue)
that your PR fixes by adding `fixes #` to the PR description.
12. If your PR fails any checks, displayed at the bottom of the PR page, fix those errors.
13. For most doc repositories, specific reviewers are automatically requested when you submit a PR.
You can request additional reviewers in the right sidebar of your PR – for example, the original
issue raiser.
Make any required changes to your PR based on reviewer feedback, repeating steps 7–9.
14. After your PR is approved by two reviewers, all checks have passed, and your branch has no
conflicts with the main branch, you can merge your PR.
If you don't have merge access, a maintainer will merge your PR for you.
You can delete the topic branch after your PR is merged.
Thank you for contributing to the docs!
---
## Configure your site
Most Consensys documentation sites are built using [Docusaurus](https://docusaurus.io/) and hosted
on [Vercel](https://vercel.com/).
You can configure site components, including the top navigation, sidebar, and footer, in the
`docusaurus.config.js` file, and server-side redirects in the `vercel.json` file.
## Top navigation
In `docusaurus.config.js`, configure the top navigation in the
[navbar](https://docusaurus.io/docs/api/themes/configuration#navbar) section of the theme configuration.
Example navbar configuration
```js title="docusaurus.config.js"
module.exports = {
themeConfig: {
navbar: {
title: 'Site Title',
logo: {
alt: 'Site Logo',
src: 'img/logo.svg',
srcDark: 'img/logo_dark.svg',
href: 'https://docusaurus.io/',
target: '_self',
width: 32,
height: 32,
className: 'custom-navbar-logo-class',
style: {border: 'solid red'},
},
items: [
{
type: 'doc',
position: 'left',
docId: 'introduction',
label: 'Docs',
},
{to: 'blog', label: 'Blog', position: 'left'},
{
type: 'docsVersionDropdown',
position: 'right',
},
{
type: 'localeDropdown',
position: 'right',
},
{
href: 'https://github.com/facebook/docusaurus',
position: 'right',
className: 'header-github-link',
'aria-label': 'GitHub repository',
},
],
},
},
};
```
## Sidebar
In `docusaurus.config.js`, pass the [sidebar](https://docusaurus.io/docs/sidebar) to the
`sidebarPath` key in your docs instance, whether it's to the `docs` section of the [`classic`
preset](https://docusaurus.io/docs/using-plugins#docusauruspreset-classic) or directly to the
[`content-docs` plugin](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-docs).
Define and customize your sidebar in a separate sidebar file (`sidebars.js` by default).
You can [manually configure](https://docusaurus.io/docs/sidebar/items) your sidebar items in
`sidebars.js`, or [auto-generate](https://docusaurus.io/docs/sidebar/autogenerated) sidebar items.
Auto-generated sidebar items require including
[metadata](https://docusaurus.io/docs/sidebar/autogenerated#autogenerated-sidebar-metadata) in the
individual pages if you want to configure relative position, custom label, custom URL, etc.
Example sidebar configuration
```js
module.exports = {
docs: [
"index",
{
type: "category",
label: "Contribute to the docs",
link: {
type: "generated-index",
slug: "/contribute"
},
items: [
{
type: "autogenerated",
dirName: "contribute",
},
],
},
{
type: "category",
label: "Create a new doc site",
link: {
type: "generated-index",
slug: "/create",
},
items: [
{
type: "autogenerated",
dirName: "create",
},
],
},
{
type: "category",
label: "Configure advanced features",
link: {
type: "generated-index",
slug: "/configure",
},
items: [
{
type: "autogenerated",
dirName: "configure",
},
],
},
],
};
```
```js
module.exports = {
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
sidebarPath: require.resolve('./sidebars.js'),
},
},
],
],
};
```
## Footer
In `docusaurus.config.js`, configure the footer in the
[footer](https://docusaurus.io/docs/api/themes/configuration#footer-1) section of the theme configuration.
Example footer configuration
```js title="docusaurus.config.js"
module.exports = {
themeConfig: {
footer: {
links: [
{
title: "Docs",
items: [
{
label: "Introduction",
to: "introduction",
},
{
label: "Get started",
to: "/category/get-started",
},
{
label: "How to guides",
to: "/category/how-to",
},
{
label: "Tutorials",
to: "/category/tutorials",
},
],
},
{
title: "Reference",
items: [
{
label: "Command line",
to: "reference/cli",
},
{
label: "REST API",
to: "/reference/rest",
},
],
},
{
title: "Community",
items: [
{
label: "Consensys Discord",
href: "https://discord.gg/ChtFaC4",
},
{
label: "Teku GitHub",
href: "https://github.com/consensys/teku",
},
{
label: "Teku documentation GitHub",
href: "https://github.com/consensys/doc.teku",
},
],
},
],
copyright: `© ${new Date().getFullYear()} Consensys, Inc.`,
},
},
};
```
## Redirects
Use the Vercel configuration file `vercel.json` to configure
[server-side redirects](https://vercel.com/docs/redirects/configuration-redirects).
Example redirects configuration
```js title="vercel.json"
{
"cleanUrls": true,
"trailingSlash": true,
"redirects": [
{
"source": "/guide/",
"destination": "/wallet/"
},
{
"source": "/guide/common-terms/",
"destination": "/wallet/"
},
{
"source": "/guide/contributors/",
"destination": "/wallet/"
}
]
}
```
---
## Deploy your doc site to production
Most Consensys documentation sites use [Vercel](https://vercel.com/) as a hosting platform.
The main benefits of using Vercel instead GitHub Pages for hosting include:
- The ease of integration with GitHub repositories.
- The ability to deploy automatic previews on pull requests.
You can deploy your documentation site in a [public GitHub repository](#public-repository) or
[private GitHub repository](#private-repository) to production using Vercel.
Private repositories require a little more setup.
## Public repository
Follow these steps to deploy your public GitHub repository to Vercel:
1. Copy the `vercel.json` file in the root of this template repository to the root of your
documentation repository.
:::note
This file contains some URL redirects from older MkDocs docs before we migrated most Consensys
docs to Docusaurus.
If your docs did not pre-exist in MkDocs, then you can remove these fields.
:::
:::caution important
Make sure `cleanUrls` is set to `true` in `vercel.json`.
This ensures that Vercel deploys the app properly without expecting trailing slashes.
:::
2. Determine the public URL that you want to use to expose the doc site.
Typically, the URL follows the format of `https://docs..consensys.net`.
You can customize this to your needs.
3. Join the [**#documentation**](https://consensys.slack.com/archives/C0272B5P1CY) channel on
Consensys Slack and ask for Vercel integration for your repository.
Provide a link to your repository in your message.
Once your repository is integrated with Vercel, any new PRs should have a Vercel bot update with a
preview link on all new commits to that PR.

## Private repository
Follow these steps to deploy your private GitHub repository to Vercel:
1. Join the [**#documentation**](https://consensys.slack.com/archives/C0272B5P1CY) channel on
Consensys Slack and ask for Vercel integration for your private repository.
Provide a link to your repository in your message.
2. Your `build.yml` file in the `.github/workflows` directory will be modified to look like the
following (you **do not** need to take this action yourself).
Essentially, this modification bypasses Vercel limitations on private repositories by having
GitHub actions build and push the static build directly to Vercel.
```yaml title=".github/workflows/build.yml"
---
name: Build and Preview
on:
pull_request:
branches:
- main
push:
branches:
- main
jobs:
build:
name: Build
runs-on: ubuntu-latest
# the environment to deploy to / use secrets from
environment: vercel
# modify the default permissions of the GITHUB_TOKEN, to only allow least privileges
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Build
uses: consensys/docs-gha/build@main
with:
GITHUB_TOKEN: ${{ github.token }}
- run: cp vercel.json ./build
- uses: amondnet/vercel-action@v41.1.4
id: vercel-action-staging
if: github.event_name == 'pull_request'
with:
github-token: ${{ github.token }}
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.ORG_ID }}
vercel-project-id: ${{ secrets.PROJECT_ID }}
working-directory: ./build
scope: consensys
- uses: amondnet/vercel-action@v41.1.4
id: vercel-action-production
if: github.event_name == 'push'
with:
github-token: ${{ github.token }}
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.ORG_ID }}
vercel-project-id: ${{ secrets.PROJECT_ID }}
working-directory: ./build
vercel-args: "--prod "
scope: consensys
github-comment: false
```
The action also provides preview URLs on
new commits to a PR.

### Set up a private repository with Vercel (for doc team only)
1. Install the [Vercel CLI](https://vercel.com/docs/cli#installing-vercel-cli).
2. Run `vercel login`.
Make sure you log in with an account that's part of the **Infura Web** team account.
3. Run `vercel link` in the root directory of your Docusaurus project.
1. Make sure to link to the **Infura Web** account and not your personal one.
2. If you previously created the project in the account, you can link to the existing one.
Otherwise, create a new one.
4. After completing the prompts, you should see a `.vercel` directory that includes a JSON file with
`Project ID` and `Org ID`.
5. Log in to the [Vercel dashboard](https://vercel.com/account/tokens) and navigate to the
**Tokens** setting.
6. Create a new token with the scope selected to **Infura Web** and expiration set to **never**.
Make sure to copy this somewhere securely (preferably 1Password), since this token will never be
shown again.
If you lose it, it must be deleted and regenerated.
There's also a security concern, since these tokens have access to the entire **Infura Web** account.
7. Navigate to your environments setting in GitHub:
`https://github.com/consensys//settings/environments`.
8. Create a new environment titled `vercel`.
9. Add three new environment secrets to the `vercel` environment:
1. `ORG_ID` - `orgId` in `project.json` in the `.vercel` directory.
2. `PROJECT_ID` - `projectId` in `project.json` in the `.vercel` directory.
3. `VERCEL_TOKEN` - Token generated from steps 5-6.
10. Copy the modified `build.yml` file and put it into the `.github/workflows` directory.
11. Navigate to your project settings on the Vercel dashboard and change the **Build & Development
Settings** under **General** for **Framework Preset** to **Other** and toggle the **Override**
for **Build Command** and leave it empty.
Save these settings.

Any new PR or push to `main` automatically triggers the action to build within GitHub and push
the artifacts to Vercel directly.
12. Edit the actions if there's something different about your doc repository (for example, the main
branch is called `master` instead of `main`).
---
## Doc site repository structure
This page describes the function of each file in your new doc site, based on
[this repository](https://github.com/consensys/docs-template).
## 📁 `.github` folder
```text title="Folder structure"
.github
├── ISSUE_TEMPLATE
│ ├── config.yml
│ ├── fix-content.yml
│ ├── new-content.yml
│ └── site.yml
├── PULL_REQUEST_TEMPLATE.md
└── workflows
├── algolia-search-scraper.yml
├── build.yml
├── case.yml
├── dependabot.yml
├── links.yml
├── lint.yml
├── release.yml
├── spelling.yml
└── trivy.yaml
```
### 📄 `PULL_REQUEST_TEMPLATE.md`
Template pre-filled in every new pull request.
### 📁 `ISSUE_TEMPLATE` folder
Contains GitHub issue forms that guide contributors when opening an issue.
### 📁 `workflows` folder
Contains all the GitHub actions for the repository.
#### 📄 `algolia-search-scraper.yml`
Action that runs in the background and populates the index that [Algolia uses to search](../configure/search.md).
#### 📄 `build.yml`
Action that builds the docs as they would be built in production, to check for any build errors.
#### 📄 `case.yml`
Action that ensures that all Markdown files have [file names](../contribute/format-markdown.md#file-names)
which are only lower case letters, digits, dashes, or underscores.
#### 📄 `dependabot.yml`
Action that reviews dependencies and automatically updates them if needed.
#### 📄 `links.yml`
Action that checks for broken links using [Linkspector](../contribute/run-link-checker.md).
#### 📄 `lint.yml`
Action that runs `npm run lint` from `package.json`.
It includes Markdown linting, TypeScript linting, and CSS styling.
#### 📄 `release.yaml`
Action that checks all recent commits made to `main` branch and automatically cuts a release in line
with [semantic versioning](https://semver.org/).
This action reads the configuration in `.releaserc.js` in the root directory of this repository.
#### 📄 `spelling.yaml`
Action that checks for spelling errors using [Vale](../contribute/run-vale.md).
#### 📄 `trivy.yaml`
Action that scans for vulnerabilities using [Trivy](https://trivy.dev/).
## 📁 `docs` folder
Contains all the Markdown and related files for the [docs](https://docusaurus.io/docs/docs-introduction)
functionality of Docusaurus.
## 📁 `scripts` folder
Contains Node.js scripts that run outside Docusaurus, typically as post-build steps.
## 📁 `src` folder
Contains all the JSX and CSS files for the [pages](https://docusaurus.io/docs/creating-pages)
functionality of Docusaurus.
```text title="Folder structure"
src
├── css
│ └── custom.css
├── pages
│ └── markdown-page.md
└── theme
└── DocItem
└── Layout
├── index.jsx
└── styles.module.css
```
### 📁 `css` folder
Contains any non-scoped CSS files.
:::caution important
We recommend leaving the default `custom.css` file by itself in this folder and not add any other files.
`custom.css` is the [global styles](https://docusaurus.io/docs/styling-layout#global-styles) file
that applies to the entire doc site.
:::
### 📁 `pages`
[Pages](https://docusaurus.io/docs/creating-pages) are one-off standalone pages that don't have
sidebars by default.
You can still [add a Markdown page](https://docusaurus.io/docs/creating-pages#add-a-markdown-page) to
this folder, and it will be rendered with the file name as the path.
Routing is file-based for any `.js` and `.tsx` file.
### 📁 `theme` folder
Contains [swizzled](https://docusaurus.io/docs/swizzling) Docusaurus theme components — local
overrides that replace or wrap the default theme implementation.
## 📁 `static` folder
Contains assets that can be directly copied on build output.
Usually images, stylesheets, favicons, fonts, etc.
See how to [reference your static asset](https://docusaurus.io/docs/static-assets#referencing-your-static-asset).
```text title="Folder structure"
static
├── img
│ ├── favicon.ico
│ ├── logo.svg
│ └── logo_dark.svg
└── robots.txt
```
#### 📄 `robots.txt`
Crawler permissions file.
The template version explicitly allows all major AI crawlers (GPTBot, OAI-SearchBot,
PerplexityBot, Google-Extended) and includes a `Content-Signal` header declaring that the
content may be used for search indexing, model grounding, and AI training.
Update the `Sitemap:` URL at the bottom to match your deployed site.
## 📁 `.cursor` folder
Contains AI coding assistant configuration for [Cursor](https://cursor.com).
```text title="Folder structure"
.cursor
├── rules
│ ├── content-types.mdc
│ ├── contributor-workflow.mdc
│ ├── editorial-voice.mdc
│ ├── markdown-formatting.mdc
│ └── terminology.mdc
└── skills
├── author-page
│ └── SKILL.md
└── style-review
└── SKILL.md
```
### 📁 `rules` folder
Cursor rules are persistent instructions loaded automatically when you work on files matching
their glob patterns.
The template ships with five rules covering editorial voice, terminology, Markdown formatting,
content types (Diataxis), and contributor workflow.
Customize these rules to match your product's terminology, link conventions, and team workflow.
### 📁 `skills` folder
Cursor skills are on-demand instructions loaded when the task matches the skill description.
The template ships with two skills:
- **`author-page`** — scaffolds and drafts new documentation pages to editorial standards.
- **`style-review`** — audits pages for voice, terminology, formatting, and content-type compliance
before a PR is submitted.
## 📄 `AGENTS.md`
Root-level context file read by AI coding agents (Cursor, Claude, etc.) when they open the
repository.
It describes the documentation areas, editorial standards, critical rules, and a lookup table of
all AI-readiness features with the file to edit and what to customize per site.
Update this file when you rename areas, add products, or change conventions.
## 📄 `.editorconfig`
[EditorConfig](https://editorconfig.org/#overview) is supported by most IDEs and text editors to
provide consistent coding styles for projects using a configuration specification.
## 📄 `.eslintignore`
[ESLint](https://eslint.org/) is used by this project since it contains Javascript, Typescript, and
React code, and lints the code to provide a consistent style for all developers and contributors.
The `.eslintignore` file contains a list of directories for ESLint to ignore when linting.
## 📄 `.eslintrc.js`
Configuration for [ESLint](https://eslint.org/) and accompanying plugins used by it to parse and
lint the code.
## 📄 `.gitignore`
A file containing files and folders for Git to ignore when adding or committing.
## 📄 `.nvmrc`
Contains the Node.js version to use for this project.
It requires installing [nvm](https://github.com/nvm-sh/nvm#installing-and-updating).
## 📄 `.prettierrc`
We recommend using [Prettier](https://prettier.io/) to format all files.
Anything not covered in `.editorconfig` is overridden or specified in this Prettier configuration file.
Running [`npm run format`](run-in-development.md#npm-run-format) runs Prettier to
format and save those changes.
## 📄 `.releaserc.js`
[`semantic-release`](https://github.com/semantic-release/semantic-release) is used to easily keep
track of version changes to documentation.
On push to the `main` branch, the `release` GitHub action takes all necessary commits based on their
type and increments the version according to [semver](https://semver.org/) conventions.
However, this is not strictly necessary, and you can remove this along with its accompanying action.
## 📄 `.stylelintignore`
[StyleLint](https://stylelint.io/) is used to lint CSS files.
This file ignores directories which do not need to be linted.
## 📄 `.stylelintrc.js`
[StyleLint](https://stylelint.io/) configuration for linting.
## 📄 `CHANGELOG.md`
[Semantic Release](https://github.com/semantic-release/semantic-release) automatically updates the
CHANGELOG file with release history and commits appended to each release.
You shouldn't modify this manually.
## 📄 `api.mustache`
This repository by default has the plugin `docusaurus-plugin-openapi-docs` installed to demonstrate
how to integrate OpenAPI documentation directly into Docusaurus.
The `api.mustache` file contains the API template for the plugin when generating the Markdown files.
## 📄 `docusaurus.config.js`
Contains all major Docusaurus configuration which is necessary to configure its behavior.
## 📄 `package-lock.json`
Used by npm when `npm install` is used to lock versions and reduce differences between development
environments if this isn't committed to the repository.
It should not be necessary to edit this file.
## 📄 `package.json`
Used by npm and contains configuration scripts, dependencies, development dependencies, and other
related dependency configurations.
## 📄 `sidebars.js`
Separate `.js` file used by Docusaurus to provide [sidebar configuration](configure-docusaurus.md#sidebar).
## 📄 `tsconfig.json`
This project uses Typescript for React.
The `tsconfig.json` contains Typescript compiler options but isn't used in compilation of the
project and is only for editor experience.
## 📄 `vercel.json`
Vercel configuration file.
The template version includes three sections:
- **`redirects`** — [server-side redirects](https://vercel.com/docs/redirects/configuration-redirects)
for moved or deleted pages.
Add an entry here whenever you rename or remove a page.
- **`headers`** — HTTP response headers added to every response.
The template sets a `Link` header on `/` that advertises `/sitemap.xml`, `/llms.txt`, and
`/llms-full.txt` to crawlers and agents, and sets `Content-Type: text/markdown` on any URL
ending in `.md`.
- **`rewrites`** — server-side rewrites that map requests with an `Accept: text/markdown` header
to the corresponding `.md` file in the build output.
This enables HTTP content negotiation so AI agents can retrieve Markdown by sending the
appropriate `Accept` header without knowing the `.md` URL in advance.
---
## Run your doc site in development
Docusaurus is a React-based project and uses npm and or Yarn project workflows.
This page describes `npm` commands to start previews, lint, build, and do other necessary
things in development.
:::note
Periodically run `npm install` before running Docusaurus to install or update dependencies.
:::
## npm commands and scripts
The following is a list of npm scripts in `package.json`.
### `npm run start`
Runs Docusaurus locally on port [http://localhost:3000](http://localhost:3000) to preview the site.
Supports automatic refresh when changes are made.
This is usually used in development while making changes to Markdown or certain configuration files.
:::note
Not all changes made are supported by the automatic refresh and may require restarting the command.
:::
### `npm run build`
Builds Docusaurus for production into the `./build` directory of the root folder of this project.
It's usually not necessary to do this in development and is usually only used by CI when building to
be deployed.
:::caution
There's an [open issue](https://github.com/facebook/docusaurus/issues/3678) regarding proper and
stable CSS insertion ordering that may differ between `npm run start` and `npm run build` results.
This is usually not an issue and can be mitigated with adding `!important` to CSS styles.
:::
### `npm run build:docs`
If you use the `docusaurus-plugin-openapi-docs` plugin for integrating OpenAPI to your docs, this
command cleans existing generated Markdown API docs and re-generates them.
This command is bundled into the `npm run build` command.
You can safely remove this script from the `package.json` if you're not using the plugin.
### `npm run swizzle`
[Swizzles](https://docusaurus.io/docs/swizzling) a component.
Swizzling allows more advanced customization of React components in Docusaurus beyond simple CSS modifications.
### `npm run deploy`
[Deploys](https://docusaurus.io/docs/deployment#deploying-to-github-pages) your Docusaurus project.
:::note
You don't need to use this command for your doc site.
:::
### `npm run clear`
Removes all generated assets, caches, or build artifacts.
If you have issues running `npm run start`, we recommend using this command.
### `npm run serve`
Serves the files generated by the build output from the `./build` directory for local viewing.
Run this after the `npm run build` command.
:::note
Since `npm run build` is for production building or debugging production build issues, you don't need
to use `npm runs serve` except in those cases.
:::
### `npm run write-translations`
Only needed where [translations](https://docusaurus.io/docs/cli#docusaurus-write-translations-sitedir)
are to be added.
### `npm run write-heading-ids`
Only needed where [translations](https://docusaurus.io/docs/cli#docusaurus-write-heading-ids-sitedir)
are to be added.
### `npm run typecheck`
Typechecks with TypeScript and `tsconfig.json`.
### `npm run typecheck-staged`
Typechecks _staged-only_ files which is used by `lint-staged` when committing.
### `npm run lint`
Combined command which includes spell check, JS/TS linting, and CSS linting.
### `npm run lint:js`
Lints JS/TS with ESLint.
### `npm run lint:style`
Lints CSS files with specific styling.
### `npm run lint:fix`
Passes the `--fix` CLI argument to `npm run lint:js` to attempt to fix issues.
### `npm run format`
Runs Prettier to format code before commit for consistency in the repo.
---
## Set up your doc site
Most Consensys documentation sites are built using [Docusaurus](https://docusaurus.io/), a static
site generator optimized for technical documentation.
See the [Docusaurus documentation](https://docusaurus.io/docs) for general information about
creating and maintaining a Docusaurus site.
This page walks you through setting up a Docusaurus site for Consensys documentation.
You'll use this template repository to set up your doc repository.
## Prerequisites
Ensure you have permission in the [Consensys GitHub organization](https://github.com/Consensys) to
create a new repository.
If you don't have permission, request it from Consensys Help Desk, which administers the GitHub organization.
## Steps
1. Go to [this repository on GitHub](https://github.com/consensys/docs-template).
2. Select the green **Use this template** button, and **Create a new repository**.

3. Fill out the details for your fork from the template.
You can prefix the repo with `docs-` and then include your project name.
For example, `docs-metamask` or `docs-infura`.

Choose **Public**, **Internal**, or **Private** depending on your needs.
For internal repositories, any member of the Consensys GitHub organization can see your
repository by default, whereas private repositories are completely hidden except to GitHub
administrators of the organization.
4. After creating the repository, navigate to the **Settings** page which is on the far right side of
the **Code** tab.
5. Ensure that the following settings are enabled/disabled on the **General** tab:
- **General**
- ❌ **Template repository**
- **Features**
- ❌ **Wikis**
- ✅ **Issues**
- ✅ **Allow forking**
- ❌ **Sponsorships**
- ❌ / ✅ **Discussions**
- ❌ / ✅ **Projects**
- **Pull Requests**
- ❌ **Allow merge commits**
- ✅ **Allow squash merging**
- ❌ **Allow rebase merging commits**
- ❌ / ✅ **Always suggest updating pull request branches**
- ❌ **Allow auto-merge**
- ✅ **Automatically delete head branches**
6. Go to the **Collaborators and teams** under **Access** on the left sidebar.
Select **Add teams**, and add **protocol-pliny** to add the Consensys developer docs team.
Add any other teams, such as your own, as needed.
7. Currently, it's not possible to easily use branch protection on `main` when using the
`semantic-release` plugin.
If you disable this, then you can enable branch protection.
You've set up your new doc site!
See how to [run and preview your site locally](../contribute/preview.md).
---
## Overview
# Consensys documentation guide
Welcome to the Consensys documentation guide.
This guide contains information about contributing to Consensys developer documentation sites and
creating new documentation sites.
## Overview
Each Consensys developer product has a documentation site, maintained by the [Consensys developer
documentation team](https://www.notion.so/consensys/Developer-documentation-team-Pliny-8965c72cd62648719e35a16935236194)
(internal page) and/or a product team.
The docs use a [docs-as-code](https://www.writethedocs.org/guide/docs-as-code/) approach and are
mostly open source, empowering developers and community members to contribute to the docs alongside
the docs team.
This guide aims to help writers, developers, product managers, and community members [contribute to
the existing doc sites](contribute) and [create new doc sites](create).
:::note
This guide assumes familiarity with Git, GitHub, and Markdown.
:::
Most of the doc sites are built using the [Docusaurus](https://docusaurus.io/) static site generator
and hosted on [Vercel](https://vercel.com/).
## List of documentation sites
The following table shows the full list of developer documentation sites supported by Consensys.
| Doc site | GitHub repository | Site platform | Hosting platform | Description |
|--------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------|---------------|------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [Teku](https://docs.teku.consensys.net/) | [`consensys/doc.teku`](https://github.com/consensys/doc.teku) | Docusaurus | Vercel | Maintained by the docs team. |
| [Besu](https://besu.hyperledger.org/) | [`hyperledger/besu-docs`](https://github.com/hyperledger/besu-docs) | Docusaurus | GitHub Pages | Maintained by the docs team. This is a Hyperledger project and has its own [Besu docs contribution guidelines](https://lf-hyperledger.atlassian.net/wiki/spaces/BESU/pages/22154225/Documentation). |
| [Web3Signer](https://docs.web3signer.consensys.net/) | [`consensys/doc.web3signer`](https://github.com/consensys/doc.web3signer) | Docusaurus | Vercel | Maintained by the docs team. |
| [MetaMask](https://docs.metamask.io/) | [`metamask/metamask-docs`](https://github.com/MetaMask/metamask-docs) | Docusaurus | Vercel | Maintained by the MetaMask team. This project has additional [MetaMask docs contribution guidelines](https://github.com/MetaMask/metamask-docs/blob/main/CONTRIBUTING.md). |
| [Linea](https://docs.linea.build/) | [`consensys/doc.linea`](https://github.com/Consensys/doc.linea) | Docusaurus | Vercel | Maintained by the Linea team. |
| [MetaFi](https://docs.cx.metamask.io/) | `consensys-vertical-apps/cx-api-docs` (private) | Docusaurus | GitHub Pages | Maintained by the docs team and the MetaFi team. |
| [MetaMask Fiat On-Ramp](https://docs.metamask-onramp.consensys.net/) | `consensys/doc.metamask-onramp` (private) | Docusaurus | Vercel | Maintained by the MetaMask Fiat On-Ramp team. |
| [gnark](https://docs.gnark.consensys.net/) | [`consensys/doc.gnark`](https://github.com/consensys/doc.gnark) | Docusaurus | Vercel | Maintained by the docs team. |
| [MetaMask Institutional](https://consensys-vertical-apps.github.io/metamask-institutional.docs/) | `consensys-vertical-apps/metamask-institutional.docs` (private) | Docusaurus | GitHub Pages | Maintained by the MetaMask Institutional team. |
| [Documentation guide](https://docs-template.consensys.net/) (this site) | [`consensys/docs-template`](https://github.com/consensys/docs-template) | Docusaurus | Vercel | Maintained by the docs team. |