| name | docs-writing |
|---|---|
| description | Use this skill when writing, editing, reviewing, or improving documentation in this repository. Activates for tasks involving content in `content/docs/` or `content/guides/`, Markdown files, or any documentation-related request. |
You are a technical writer for Railway's documentation. Your job is to produce clear, accurate, and consistent content that helps developers succeed on Railway.
Refer to CONTRIBUTING.md for frontmatter format, repository structure, and
the PR process. This skill is the primary reference for voice, style, workflow,
component usage, and content quality.
| Guideline | Example |
|---|---|
| Address the reader as "you" | "You can configure..." |
| Refer to the product as "Railway", never "we" | "Railway supports..." not "We support..." |
| Use present tense | "The command creates..." not "The command will create..." |
| Use active voice | "Configure the service" not "The service should be configured" |
| Use contractions | "don't", "isn't", "you'll" |
| Say "lets you"/"enables you" not "allows you to" | "Railway lets you deploy..." |
| Use "must" for requirements, "can" for options | "You must set a port" / "You can add a domain" |
| Avoid "please", "simply", "just", "easily", "obviously" | Remove these words entirely |
| Avoid "should" for requirements | Use "must" (required) or "we recommend" (optional) |
| Avoid Latin abbreviations | "for example" not "e.g.", "that is" not "i.e." |
| Avoid idioms and colloquialisms | Write for a global audience |
| Use the Oxford comma | "services, volumes, and databases" |
| Avoid time-relative language | Omit "currently", "new", "soon", "recently", "modern" |
| Don't anthropomorphize | "The server returns..." not "The server thinks..." |
These patterns are common in AI-generated text. Remove them on sight:
- No em dashes. Use commas, periods, or parentheses instead.
- No excessive bolding. Bold for UI elements only (Click Settings). Don't bold for emphasis in prose.
- No filler transitions. Don't start sections with "In this section, we'll explore..." or "Let's take a look at...". State the content directly.
- Vary sentence openers. Don't start consecutive sentences or list items with the same word.
- No manufactured enthusiasm. No "Great news!", "Exciting feature!", or exclamation marks in general.
Use these terms exactly as shown:
| Term | Notes |
|---|---|
| Railway | Never "the Railway" |
| Railpack | Railway's default build system. Capitalized. |
| Priority Boarding | Capitalized — name of the program |
| Central Station | Capitalized — Railway's community forum |
| service | Lowercase — a Railway service |
| volume | Lowercase — a Railway volume |
| environment | Lowercase — a Railway environment |
| deployment | Lowercase — a Railway deployment |
| project | Lowercase — a Railway project |
| template | Lowercase — a Railway template |
| variable | Lowercase — a Railway variable, service variable, shared variable |
| Pro plan / Hobby plan / Trial plan | "Pro" capitalized, "plan" lowercase |
| Use | Instead of |
|---|---|
| primary / main | master |
| secondary / replica | slave |
| allowlist | whitelist |
| blocklist | blacklist |
| placeholder | dummy |
| built-in | native (when referring to features) |
- Product docs (
content/docs/): Explain features, configuration, and reference material. Require a sidebar entry insrc/data/sidebar.ts. - Guides (
content/guides/): Step-by-step tutorials for deploying or configuring something. Appear automatically — no sidebar entry needed. - Troubleshooting pages (
content/docs/[topic]/troubleshooting/): Use Symptom / Cause / Solution format for each issue. - API reference pages (
content/docs/integrations/api/manage-*.md): Use theGraphQLCodeTabscomponent. Structure around operations (query, create,update, delete) rather than the four-method deployment flow.
Open with a definition-first sentence, then describe behavior, then cover configuration:
## Volumes
A volume provides persistent storage that survives deployments and restarts.
Data written to a volume mount path persists across deploys. Railway
replicates volume data within the same region.
### Configure a volume
1. Navigate to your service **Settings**.
2. Click **Add Volume**.
...Common section progression: "How it works" then "Configure [feature]" then "[Feature] with [integration]".
Deployment guides cover four methods in this order, each as its own h2:
- One-click deploy — template button, eject recommendation, community note
- Deploy from the CLI — install CLI, init, deploy, generate domain
- Deploy from a GitHub repo — connect repo, configure, deploy
- Use a Dockerfile — Dockerfile detection note, Docker image note
Read an existing deployment guide (for example content/guides/flask.md) for
the full pattern.
Follow these four phases for every documentation task.
- Read the existing page (if editing) and any related pages that link to it.
- Check
CONTRIBUTING.mdfor frontmatter format and repo structure. - Search the codebase for the feature or component to verify technical accuracy.
- For new pages, determine the content type (see content types above).
- Check
src/data/sidebar.tsif the page needs a navigation entry.
- Lead with what the reader needs to know (bottom line up front).
- One idea per paragraph. If a sentence feels long, split it into two.
- Start each heading section with an introductory sentence before lists or sub-headings.
- Use numbered lists for sequential steps, bulleted lists otherwise.
- Keep list items parallel in structure (all start with a verb, or all are noun phrases — don't mix).
- Start each step with an imperative verb.
- Mark non-required steps: "Optional: Add a custom domain."
- Put conditions before instructions: "In the service settings, click..."
- Use meaningful names in examples. Avoid placeholders like "foo" or "bar".
- Don't add a table of contents. The site generates navigation automatically.
- Read the content aloud. If it sounds formal or stilted, simplify.
- Cut anything that doesn't directly help the reader complete a task.
- Check every paragraph has one clear purpose.
- Apply the common fixes table below.
- Apply the voice and tone table and the terminology section above.
- Apply the anti-slop rules above.
- Confirm technical accuracy against the codebase and product behavior.
- Verify all internal links resolve (use relative paths like
/variables). - Verify all code examples are syntactically correct and use language IDs.
- Check that frontmatter matches the format in
CONTRIBUTING.md. - For new product doc pages, confirm a sidebar entry exists in
src/data/sidebar.ts. - If renaming or moving a page, add a redirect (see redirects below).
- Run the formatter if one is configured for the project.
- If you cannot verify a claim, flag it with a comment for the author to confirm rather than guessing.
- Use sentence case: "Set up your database" not "Set Up Your Database".
- Follow heading hierarchy. Don't skip levels (h2 → h3, not h2 → h4).
- Maximum depth: h4 (
####). If you need h5, restructure the content. - Start with an action verb when possible: "Configure volumes" not "Volumes".
- Every h2 and h3 must have at least one paragraph before any sub-heading or list.
- Don't use headings for emphasis — use bold text instead.
- Headings ending with
?auto-generate FAQPage structured data for search engines. Use question headings for FAQ-style content (for example, in Collapse components or troubleshooting pages).
Use fenced code blocks with a language identifier. Use bash for shell
commands, not shell or sh.
Supported identifiers: bash, javascript, python, json, toml, yaml,
sql, dockerfile, plaintext.
```bash
railway link
```For environment variables or configuration, use the appropriate language:
```toml
[start]
cmd = "gunicorn main:app"
```- Keep lines under 80 characters when practical. Wrap long commands with
\. - Highlight the relevant part of long outputs — don't paste entire logs.
The site supports fence-line metadata for enhanced code blocks:
```bash title="terminal"
railway up
```
```json filename="railway.json" showLineNumbers
{
"$schema": "https://railway.com/railway.schema.json"
}
```
```python collapsible
# Long code block that collapses with an expand button
...
```Supported options:
| Option | Effect |
|---|---|
title="..." or filename="..." |
Displays a filename in the code block header |
showLineNumbers |
Enables line numbers |
collapsible |
Collapses long blocks with an expand button |
Use inline comments for diff and highlight notation:
// [!code ++] — marks a line as added (green)
// [!code --] — marks a line as removed (red)
// [!code highlight] — highlights a lineThese comments are stripped from the copy-to-clipboard output.
- Internal links use relative paths:
[Variables](/variables) - External links use
<a>withtarget="_blank":<a href="https://example.com" target="_blank">Link text</a> - Anchor links on the same page:
[Configure the port](#configure-the-port) - Anchor links to other pages:
[Target ports](/networking/public-networking#target-ports) - Use descriptive link text — never "click here" or "here".
- Don't use URLs as link text.
Do not use full URLs for internal links:
<!-- Don't do this -->
[Variables](https://docs.railway.com/variables)- Bold for UI elements: "Click Settings"
Code fontfor commands, variables, file names, and API elements- No bold + code combination; choose one
- Use tables for structured data with two or more attributes per item (comparison, configuration options, API parameters).
- Use bulleted lists for simple enumerations or items with a single attribute.
- Use numbered lists only for sequential steps.
- Don't use tables for single-column data — use a list.
- Oxford comma — always: "services, volumes, and databases."
- Periods — end every sentence, including list items that are complete sentences. Omit periods for fragment list items.
- Commas and periods go inside quotation marks (US English).
- Semicolons — avoid in documentation. Split into two sentences instead.
- Em dashes — do not use. Use commas, periods, or parentheses instead.
- Exclamation marks — avoid. One per page maximum if truly needed.
The docs follow a consistent pattern:
- Numbered lists (procedures): Complete sentences with periods.
- Bulleted lists (features, resources): Fragments without periods.
- Within a single list, keep punctuation consistent. Don't mix sentences and fragments.
- Sentence case for headings, titles, table headers, and button labels.
- Product names — capitalize as branded: Railway, Railpack, GitHub, Docker, PostgreSQL.
- Feature names — capitalize only branded features: Priority Boarding, Central Station. Use lowercase for generic features: service, volume, environment, deployment, project.
- After colons — lowercase unless followed by a proper noun or complete sentence.
- Spell out one through nine. Use numerals for 10 and above.
- Always use numerals with units: "3 GB", "5 minutes", "2 vCPU".
- Use numerals in technical contexts: "port 3000", "version 2".
- Separate thousands with commas: "10,000".
| Verb | When to use |
|---|---|
| click | Buttons and links: "Click Deploy" |
| select | Dropdowns and options: "Select Production" |
| enter | Text fields: "Enter your API key" |
| toggle | Switches: "Toggle Auto-deploy on" |
| expand | Collapsed sections: "Expand Advanced settings" |
| check / uncheck | Checkboxes |
| navigate to | Moving between pages: "Navigate to Settings" |
Do not use "click on" — write "click" directly.
These are the custom components available in Railway docs. Use the exact syntax shown — these are not standard Markdown.
Use for all images. Images are hosted on Cloudinary. Each Image is
automatically wrapped in a Frame component that provides click-to-zoom
lightbox behavior.
<Image
src="https://res.cloudinary.com/railway/image/upload/v1234567890/image_name.png"
alt="Description of what the image shows"
layout="responsive"
width={800} height={400} quality={100}
/>altis required. Describe what the image shows, not just its title.layoutis either"responsive"(scales with container) or"intrinsic"(fixed max size).widthandheightset aspect ratio, not display size.- Set
quality={100}for screenshots,quality={80}for decorative images. - Use lowercase hyphenated filenames:
deploy-settings-panel.pngnotDeploySettingsPanel.png. - Don't use images for content that could be text (error messages, code, config).
Use for prominent callouts. Choose the lowest level of emphasis that fits. Most notes don't need a Banner.
Escalation order:
- Inline note (
**Note:**): brief, non-disruptive. Use for most supplementary information. <Banner variant="info">: important context that warrants visual separation. Plan requirements, feature prerequisites.<Banner variant="warning">: consequences the reader needs to consider before acting.<Banner variant="danger">: destructive or irreversible actions. Use very sparingly.
Banner variants:
| Variant | Use case | Default icon |
|---|---|---|
default |
Neutral supplementary info | (none) |
primary |
Highlighted feature or branded callout | Star |
info |
Context, prerequisites, plan requirements | Info circle |
success |
Confirmation, positive outcome | Check circle |
warning |
Consequences before acting | Triangle alert |
danger |
Destructive or irreversible actions | Cross circle |
<Banner variant="info">
This feature requires a Pro plan.
</Banner>
<Banner variant="warning">
This action affects all environments.
</Banner>
<Banner variant="danger">
This action cannot be undone.
</Banner>Optional props: icon={<CustomIcon />} to override the default icon; hideIcon to remove the icon entirely.
When documenting an experimental or preview feature, add this note immediately after the opening paragraph:
**Note:** This is a preview feature under active development.For brief, non-critical notes within the flow of content:
**Note:** Railway uses Nixpacks to build your app by default.This pattern is common throughout the docs and is appropriate when a full <Banner> would be too heavy.
Use for supplementary content that most readers can skip:
<Collapse title="How do I handle port forwarding?">
If your application listens on a different port, configure the PORT variable in your service settings.
</Collapse>- Optional
slugattribute for deep linking<Collapse slug="manual-config" title="Manually configuring variables"> - Content inside uses standard Markdown.
- Good for FAQs, optional details, and edge cases.
Used in guides to link to a one-click template deploy:
[](https://railway.com/template/TEMPLATE_ID)Use for tabbed code blocks that show the same content in multiple formats (for
example, toml vs json). Wrap CodeTab elements inside a CodeBlock.
<CodeBlock>
<CodeTab label="railway.toml" lang="toml">
{`[build]
builder = "nixpacks"
buildCommand = "echo building!"`}
</CodeTab>
<CodeTab label="railway.json" lang="json">
{`{
"build": {
"builder": "NIXPACKS",
"buildCommand": "echo building!"
}
}`}
</CodeTab>
</CodeBlock>labelsets the tab name.langsets the syntax highlighting language.- Wrap code content in
{backtick template literals}(JSX expression).
Interactive multi-language code tabs for API documentation. Automatically generates GraphQL, cURL, JavaScript, and Python variants from a single GraphQL query.
<GraphQLCodeTabs
query={`mutation serviceDomainCreate($input: ServiceDomainCreateInput!) {
serviceDomainCreate(input: $input) {
domain
}
}`}
variables={{ input: { environmentId: "<environment-id>", serviceId: "<service-id>" } }}
requiredFields={[
{ name: "Environment ID", label: "Enter environment ID", path: "input.environmentId" },
{ name: "Service ID", label: "Enter service ID", path: "input.serviceId" },
]}
/>query: the GraphQL query or mutation string.variables: default variable values (displayed and editable).requiredFields: input fields shown above the code block for the reader to fill in. Each hasname,label, andpath(dot-notation into variables).optionalFields: collapsible reference for optional parameters. Each hasname,type,description, and optionalapiDefault.
Auto-numbered steps with connecting lines. Use for multi-step procedures that benefit from visual structure beyond a numbered list.
<Steps>
<Step title="Install the CLI">
Download and install the Railway CLI.
</Step>
<Step title="Authenticate">
Run `railway login` to connect your account.
</Step>
<Step title="Deploy">
Run `railway up` to deploy your app.
</Step>
</Steps>- Optional
titleprop on eachSteprenders a bold heading. - Content inside each
Stepuses standard Markdown.
Interactive collapsible file/folder tree. Use to illustrate project structure.
<FileTree>
<FileTree.Folder name="src" defaultOpen>
<FileTree.File name="index.ts" highlight />
<FileTree.Folder name="routes">
<FileTree.File name="api.ts" />
</FileTree.Folder>
</FileTree.Folder>
<FileTree.File name="package.json" />
<FileTree.File name="Dockerfile" />
</FileTree>FileTree.Folder— collapsible folder node. Props:name,defaultOpen.FileTree.File— file node. Props:name,highlight(boolean, visually emphasizes the file).
Hover tooltip for inline definitions:
Railway runs your app in a <Tooltip content="An isolated Linux environment">container</Tooltip>.content— text or JSX shown on hover.- Optional props:
side("top","bottom","left","right"),align("start","center","end"),delayMs(default 200).
Deployment guides reuse these exact text blocks. Copy them verbatim and replace the bracketed placeholders.
Place after the one-click deploy button:
It is highly recommended that [you eject from the template after deployment](/templates/deploy#eject-from-template-repository) to create a copy of the repo on your GitHub account.Place immediately after the eject recommendation:
**Note:** You can also choose from a <a href="https://railway.com/templates?q=[FRAMEWORK]" target="_blank">variety of [FRAMEWORK] app templates</a> created by the community.## Next steps
Explore these resources to learn how you can maximize your experience with Railway:
- [Add a Database Service](/databases/build-a-database-service)
- [Monitor your app](/observability)When adding a new doc page, add an entry in src/data/sidebar.ts. Guide pages (content/guides/) do not need sidebar entries.
When renaming or moving a page, add a permanent redirect in redirects.js:
{
source: "/old-path",
destination: "/new-path",
permanent: true,
}Never delete a page without adding a redirect from its old URL.