Style Guide Contributions import { Details } from "~/components"; The Cloudflare Docs are open source and hosted on the cloudflare-docs repository on GitHub. This means that anyone, including those who are not part of the Cloudflare organization, can contribute to them. We welcome all suggestions that help keep our docs high quality and up to date. To contribute to our docs, you will need to create an account on GitHub (if you do not have one already) and log in. Then you have three options: GitHub issue: Quickly submit a general suggestion. Quick edit (edit button): Quickly create a pull request. This is best if you want to edit a single page in your web browser and do not need to preview your changes. Full development: Create a pull request. This is best if you want to edit multiple pages and preview your changes. This can be done in your web browser (with Codespaces) or on your local machine (with Visual Studio Code). In addition to using the Cloudflare Style Guide for guidance on grammar and style, we recommend browsing our components to add additional formatting such as buttons, tabs, and collapsible sections. Create a GitHub issue To create a GitHub issue: Log in to GitHub and go to the cloudflare-docs repository. Select Issues and then New issue. Select the issue type, fill out the form, and select Create. Learn more about creating GitHub issues. Quick edit To quickly create a pull request using the edit button: Log in to GitHub. Go to the page you want to edit in the Cloudflare Docs Select Every page in the Cloudflare Docs (including this one) has an Edit button on the right sidebar and an Edit page button on the very bottom of the page. The page's Markdown opens. :::note The first time you create a pull request in the cloudflare-docs repo, you will see a GitHub landing page that says "You need to fork this repository to propose changes." Select Fork this repository. All of your future pull requests for cloudflare-docs will write to a new branch on your fork. ::: Make your edits and select Commit changes. In the form, update the Commit message with the product you changed in brackets and a brief description of your changes. For example “[Images] Fixed broken link." Update the Extended description with more details about what you changed and why. The more details, the better. Select Propose changes > Create pull request > Create pull request again. Full development To edit and create a pull request with the full development workflow: Log in to GitHub and fork the cloudflare-docs repository. If you are editing in your web browser (with Codespaces), move on to step 3. If you are editing on your local machine (with Visual Studio Code): * (Required) Install Node.js (version 24 or later). * (Recommended, but not required) Install Vite+ and use vp env to manage Node.js and package manager versions. * (Required) Clone the fork to your local machine. Create a branch from your fork (or from your clone). Make your edits. Preview your edits by installing the dependencies and starting the local development server: pnpm install pnpm run dev A link appears in the terminal, for example https://localhost:1111/, where you can preview your changes. The preview updates automatically as you edit. Commit your changes. Push your commits to your branch and then back to your fork. Return to GitHub and create a pull request from your committed changes. In the description form, add the product you changed in brackets and a brief description of your changes. For example, "[Images] Fixed broken link." After you create an issue or PR After you create an issue or PR, a member of the Cloudflare organization will review your suggestion. Here is what to expect: A member of the Cloudflare organization may tag others for technical or content reviews or feedback. If your suggestion requires more information, a member of the Cloudflare organization may comment with a follow-up or clarification question. If they add the more-information-needed tag, the issue or pull request will automatically close if you do not respond within 14 days. If your changes are approved: For GitHub issues, a Cloudflare member might create and link a new pull request that addresses your request. When they merge the PR, they will also close your issue. For GitHub PRs, the Cloudflare member will merge your PR. If your suggestion is not approved, the Cloudflare member will respond with the reasoning and close your issue or PR. Thank you for contributing to our open-source ecosystem and being a part of the Cloudflare community. Content reviews We work (and appreciate working) in GitHub, but it's not a perfect tool by any means. We've added several ergonomic improvements to help us triage incoming work, streamline reviews, and automate communication. Triage work To help our writers triage work (and help with backend reporting), we automate a few labels and issue / pull request assignment. Pull requests For pull requests, we use a specific GitHub action to add labels and assign codeowners. Label products: We add labels for the top-level product folder, which helps writers scan incoming pull requests and see which are relevant to them. Label size: We add labels for the size of the pull request, which helps writers see the relative size of the difference. It's not a perfect measure, but we use the lines changed to estimate the size of the pull request: Assign codeowners: We use our CODEOWNERS file to automatically assign people to pull requests based on the files changed. This assignment helps writers scan and filter to see which pull requests are relevant to them. Issues For issues, we use a similar GitHub action to add labels and assign codeowners. Our script treats issues because usually they contain links to our site instead of files within the repository. We grab the associated links in the issue description fields and then use those to assign writers (again based on CODEOWNERS) and add product labels. Streamline reviews To streamline reviews, we use several automations to help solve common reviewer issues. Will this break anything? We have one required check that runs on every commit, CI. This check makes sure that: The site builds correctly. All internal links are valid. There are no infinite redirects. Specific pages and functionality in our docs behave as expected. Who needs to approve this? We commonly get questions about approvals, especially for pull requests that touch multiple product areas (or our components). On open pull requests, the Cloudflare Docs Bot posts a Review coverage comment that shows which areas still need a CODEOWNERS approval, suggests contacts for those areas, and summarizes the areas already covered. Expand the CODEOWNERS mappings section to see the exact patterns and owners for the ownership areas displayed in the comment. The bot skips draft, closed, and spam/off-topic pull requests. What changed? We use a GitHub action to publish preview builds for every commit on a pull request (and comment those links on the pull request). This action ensures that reviewers can see exactly what the site and content will look like when they're rendered (and not just look at the changed markdown in GitHub). We are in the process of migrating to Workers Builds, which provides that functionality natively. Based on feedback, we have also added a before/after table of links to help reviewers easily find links in the preview builds. Is there anything else I need to check? One difficult thing to check is potential redirects when a pull request renames or deletes content file paths. We have a specific action that posts a comment to help reviewers identify and then check these paths. Automate communication We automate communication primarily through the no-response GitHub Action. Being open source means that we accept issues and pull requests from anyone! And a lot of these are either self explanatory or have enough context for us to follow up on them. The ones without enough context, however, are often painful (especially in a busy repo like ours). A writer has to ask for more detail, then remember to check back in, and then sometimes re-ask for more detail, and then check in again. To help avoid some of this mental toil, we'll ask a question and then apply the more-information-needed label. This label starts a 14-day clock for the author to respond. If they do respond, the label gets removed and the conversation can continue. If they don't respond, the issue automatically gets closed with a comment explaining why. This workflow - we hope - balances the needs our of team with a healthy respect for our contributors. Stale issues We intentionally avoid the stale workflow that closes pull requests or issues that have been inactive for a specific period of time. In our opinion, this workflow causes more friction and frustration than it solves. Just because something has been around for a year doesn't mean it's not still relevant. Contribute to Cloudflare documentation with AI The cloudflare-docs repository includes an AGENTS.md file that helps AI coding agents understand the structure, tooling, and conventions of the repository so they can make correct, buildable changes when contributing to documentation. AGENTS.md is a simple, open format for guiding coding agents. The repository includes configuration for the following AI tools out of the box: OpenCode Windsurf Claude Code Gemini CLI GitHub Copilot (via VS Code) Agent skills, commands, and agent definitions all live in .agents/ and are symlinked into the expected locations for each tool automatically. Style Guide import { CardGrid, LinkCard } from "~/components"; Use this guide whenever you write or review Cloudflare content, whether it lives in the documentation or in the product dashboard. Following it is what keeps the whole site reading as though one careful author wrote every page, which also makes the content clearer for readers and simpler to translate. The guide is organized around the way you actually work, in five stages: contribute a change, plan the content, write it in the Cloudflare style, build the page, and, for the Cloudflare team, run the site. Contribute Start here. Make a change and get it merged. Plan your content Decide what kind of page you are writing and where it lives. Style and grammar Write the page in the house voice, grammar, and formatting. Build the page Author the page in MDX, set its metadata, and add components. How we docs How the Cloudflare team runs the site. This section is Cloudflare-specific internal process. Guidelines for cURL commands We follow several formatting conventions for cURL commands. Components To automatically incorporate our conventions into your examples, use: APIRequest: For examples hitting endpoints in the Cloudflare API schema. CURL: For other cURL commands. Parameter names Use long parameter names for clarity: --header (instead of -H) --request (when needed, instead of -X) --data (instead of -d) You do not need to use the --url parameter since it is the main cURL parameter. Also, the URL does not need to be enclosed in double quotes ( ""), except if it contains a ? character (that is, when it includes a query string). Indentation Use two spaces to indent request or response bodies (the additional data included in the request/response). For requests with body content, start indenting when you get to the body part (the line after --data in the examples in this page). This means that the URL, any headers, and the line containing the --data parameter should not be indented. Requests without a body should not be indented also, to make them consistent with requests containing a body. Do not use jq as part of cURL examples jq is a separate tool that not everyone will have installed. cURL examples should not include response formatting through jq as part of the example. If you must suggest the use of this tool, you can add a link to the Make API calls page in Fundamentals, which mentions this tool. Do not repeat the existing content about jq near the cURL example. Request guidelines Preliminary notes Make sure not to use typographical or smart quotes in a cURL command, or the command will fail. Placeholders in the URL should follow the same format as in the API documentation: $ZONE_ID Placeholders in the request body (that is, the data included in a POST/ PUT/ PATCH request) should use angle brackets: The same placeholder name should correspond to the same value – use different placeholder names for different ID values. You can use the same request placeholders in the response, if they should match the values in the request. Authentication HTTP headers If using Email + API Key authentication, include the following arguments in the cURL command to add the two required HTTP headers to the request: --header "X-Auth-Email: $CLOUDFLARE_EMAIL" \ --header "X-Auth-Key: $CLOUDFLARE_API_KEY" \ :::note Ending slashes included to facilitate copy and paste. Do not include the last slash if this is the last line of the cURL command. ::: If using API Token (the preferred authentication method), include the following arguments in the cURL command to add the required HTTP header to the request: --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ Request without body content ( GET, DELETE) For GET requests, do not include the --request GET command-line argument, since it is the default where the request does not include a body and it is not recommended for GET/ POST requests: GET request template curl {full_url_with_placeholders} \ --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" curl https://api.cloudflare.com/client/v4/zones/$ZONE_ID/firewall/rules \ --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" DELETE request template curl --request DELETE \ {full_url_with_placeholders} \ --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" Requests without a body do not need syntax highlight, but we use bash syntax highlighting to highlight the several delimited strings. Request with JSON body content ( POST, PUT, PATCH) Make sure to include a Content-Type header if the request includes a body. For requests with JSON content, the header should be Content-Type: application/json. This header should appear after the authentication headers. For POST requests with a body, do not include the --request POST command-line argument, since it is the default when the request includes a body. POST request template curl {full_url_with_placeholders} \ --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ --header "Content-Type: application/json" \ --data '({|[) (...JSON content, pretty printed, using 2-space indents...) (}|])' curl https://api.cloudflare.com/client/v4/zones/$ZONE_ID/firewall/rules \ --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ --header "Content-Type: application/json" \ --data '[ { "filter": { "id": "" }, "action": "allow", "description": "Do not challenge login from office" } ]' PUT/ PATCH request template curl --request (PUT/PATCH) \ {full_url_with_placeholders} \ --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ --header "Content-Type: application/json" \ --data '({|[) (...JSON content, pretty printed, using 2-space indents...) (}|])' Enclose the JSON payload ( the --data command-line argument) in single quotes ( ') instead of double quotes because it requires less escaping (strings in JSON must be delimited using double quotes). Escaping a single quote in the body The recommended way of escaping a single quote inside the body is the following (assuming the user will run the command in a bash-like terminal): Replace the single quote ' with '\'' Which means "close string, add escaped single quote, begin string again". curl https://api.cloudflare.com/api/v4/zones/$ZONE_ID/page_shield/policies \ --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ --header "Content-Type: application/json" \ --data '{ "value": "script-src myapp.example.com cdnjs.cloudflare.com https://www.google-analytics.com/analytics.js '\''self'\''" }' POST requests without a body If you have a POST request without a body, you must add the --request POST argument explicitly to the cURL command. curl --request POST \ {full_url_with_placeholders} \ --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" Additional information Code blocks with example requests that include a JSON body should use bash syntax, similarly to example requests without a body. Full request example curl https://api.cloudflare.com/api/v4/zones/$ZONE_ID/page_shield/policies \ --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ --header "Content-Type: application/json" \ --data '{ "description": "My first policy in log mode", "action": "log", "expression": "http.host eq \"myapp.example.com\"", "enabled": "true", "value": "script-src myapp.example.com cdnjs.cloudflare.com https://www.google-analytics.com/analytics.js '\''self'\''" }' Response guidelines Include the complete response (including any empty error and message arrays, if present) using json syntax highlighting. A response starts either with an object ( { ... }) or a list ( [ ... ]). The initial character should appear on its own line, as well as the last character. ({|[) (...JSON content, pretty printed, using 2-space indents...) (}|]) If there are IDs that were obtained using a previous command, or if their exact value is not relevant in the current context, use a placeholder (for example, ) instead of the ID. The same placeholder name should correspond to the same value. Use different placeholder names for different ID values. Response excerpts or snippets containing the most relevant parts of the response body should mention that they do not correspond to the entire response. Full response example { "result": { "id": "", "paused": false, "description": "do not challenge login from office", "action": "allow", "priority": null, "filter": { "id": "", "expression": "ip.src in {2400:cb00::/32 2803:f800::/32 2c0f:f248::/32 2a06:98c0::/29} and (http.request.uri.path ~ \"^.*/wp-login.php$\" or http.request.uri.path ~ \"^.*/xmlrpc.php$\")", "paused": false, "description": "Login from office" } }, "success": true, "errors": [], "messages": [] } API content import { DirectoryListing } from "~/components"; Our approach to API documentation aims to: Reduce internal and external user frustration Align with industry standards in terms of naming conventions and descriptions Create world-class content that is just as good, or better, than very popular API documentation By ensuring Cloudflare's API content is straightforward, easy to navigate, and consistent, we can create world-class API content that eliminates user frustration and serves as an example of good API documentation. Method types & common verbs The verb examples are a small handful of commonly used verbs associated with a method, but you should not feel limited and only use the verbs in the examples. When writing the endpoint title, use the root form of the verb. For example, “Create a namespace.” For the endpoint description, use the present tense of the verb. For example, “Creates a namespace under the given title.” Additionally, using the method type as the verb in the title and description is okay. For example, using the method GET and including it in the description as “Gets embed code” is acceptable. Method Purpose Verb examples GET Retrieves a resource Gets, Lists, Returns, Downloads POST Creates a resource Creates, Watches, Inserts, Adds PUT Updates or creates an existing resource Updates, Modifies, Adds PATCH Partially modifies an existing resource Updates, Edits, Changes DELETE Removes the resource Deletes, Removes, Cancels Deprecated APIs The purpose of Deprecated API content is to communicate that Cloudflare no longer supports an endpoint and to provide users with an alternative option. Tone instructional, straightforward content_type reference Structure Required components Deprecated endpoint name: Must match what existed in the non-deprecated Endpoint. Context: Brief description of what is happening, why Cloudflare is deprecating this endpoint, and any other important information. Avoid using time-bound descriptors (today, tomorrow, in one week, etc). Instead, be specific when including dates. Replacement: A description of and/or link to the alternative endpoint OR an explanation as to why Cloudflare is removing the capability of that endpoint. End of life date: The date by which users will no longer be able to use that endpoint. Format full month name, date, and year (May 10, 2021). Optional components A complete list of endpoints or related APIs that are being deprecated Additional information Add API deprecation notices to the API deprecations page by deprecation date and not alphabetically by endpoint. When an endpoint will be deprecated in a specified timeframe but is still available, add a note to the endpoint description about the upcoming deprecation (" will be deprecated on . Use the instead."). Examples Cloudflare Images - Create authenticated direct upload URL v1 End of life date: July 1, 2022 This endpoint is deprecated in favor of using v2, which allows you to control metadata, define an access policy, and get the image ID. Deprecated API: POST accounts/:account_identifier/images/v1/direct_upload Replacement: POST accounts/:account_identifier/images/v2/direct_upload Endpoints An endpoint is used to make HTTPS requests, and the GET, POST, PUT, PATCH, and DELETE methods dictate how to interact with the resource. Structure Required Components :::note The required components apply to newly created endpoints. Existing endpoints will not be modified. ::: Title: Title of the endpoint using sentence casing (first word capitalized). The titles do not use punctuation marks at the end of the title. Simple cases usually take one of the following forms: Endpoints that act on/return a single item: verb + indefinite article + singular resource name. Example: Get a list item Endpoints that act on/return a collection of items: verb + plural resource name. Example: Get list items Description: Describes what the endpoint does or how it should be used. Use punctuation at the end of the description. Plan availability: Lists the plan required to use the endpoint, such as Free, Pro, Business, or Enterprise. Method: Includes the type of method, such as GET, POST, PUT, PATCH, or DELETE. Endpoint: Lists the endpoint and should be stylized as code snippet. When an endpoint will be deprecated in a specified timeframe but is still available, add a note to the endpoint description about the upcoming deprecation (" will be deprecated on . Use the instead"). Refer to Deprecated APIs for more information. Optional components Required permissions: Additional permissions at the user level that are required to use the endpoint. Writing guidelines When writing the titles and descriptions, keep our voice and tone in mind. Be concise and remember our users come from a variety of technical levels. Also, write in the active voice as much as possible to avoid sounding robotic and to make the information easier to understand. Below are some examples of endpoint titles and descriptions for reference: Get domain: Fetches a single domain. List workers: Fetches a list of uploaded workers. List pools: Lists configured pools. Create waiting room: Creates a new waiting room. Update health check: Updates configured health checks. Example Title: Get user audit logs Description: Gets a list of audit logs for a user account. Plan availability: Free, Pro, Business, Enterprise Method: GET Endpoint: user/audit_logs Get started - API The Get started section provides a brief overview of the Cloudflare’s API and lists requirements and tasks users must complete before successfully making their first request. Structure Required components Overview: High-level explanation of Cloudflare’s API and includes information about our architectural style, schema, and base URL. Authentication: Explains how users can authenticate with the Cloudflare API and how users should or can utilize API tokens, API token templates, and API token permissions. Example Overview: Cloudflare's API exposes the entire Cloudflare infrastructure via a standardized programmatic interface. Cloudflare’s API uses REST and returns JSON responses, and the latest version is v4. Recommended workflow: Sign up for a Cloudflare account. Create an API token. (Optional) Use API token templates and token permissions. Make your first request. API content types import { DirectoryListing } from "~/components" Parameters A parameter is an option passed with the endpoint to receive specific information or values. Values default, minimum, and maximum Structure Required Components Name: Name of the parameter formatted as code snippet. Data type: Indicates if the parameter is a string, integer, boolean, object, or array. Description: Describes what the parameter does. Use a noun phrase for strings, integers, objects, and arrays. Use a verb for booleans. End description with a period. Required status: Indicates whether the parameter is required Optional components Constraints: Lists default, minimum, or maximum values for the parameter. Writing guidelines When writing the titles and descriptions, keep our voice and tone in mind. Be concise and remember our users come from a variety of technical levels. Some parameter descriptions are more factual, like deviceName, and do not make sense to start with a verb. Other parameters will lend well to beginning with a verb, and this difference is okay. Try to avoid the passive voice and aim to describe what the parameter does or what it is used for in a concise sentence users can understand. Below are some examples of parameter descriptions for reference: deviceName: The device name. version: The Cloudflare One Client version. per_page: Sets the maximum number of requested results. enabled: Enables or disable a load balancer. ASN: The Autonomous System Number (ASN) used to advertise a prefix. Example Name: actor.ip Data type: string Description: Filters a request by specific IP address or valid CIDR range. Required status: Not required Values: No listed default, minimum, or maximum, values. Resources The resource groups all of the associated endpoints together. Structure Required components Name: Name of the resource that serves as a top-level grouping. Short noun phrase. Description: Describes the collective group of endpoints that fall under the resource and provides a high-level description of the endpoints. Example Name: Audit logs Description: A log of changes made to your Cloudflare account. Build the page import { DirectoryListing } from "~/components"; This section covers how a page is put together: the MDX syntax you write in, the frontmatter metadata every page carries, and the components you can add for richer formatting. Start with the Markdown and MDX basics, then set the frontmatter, then reach for components as you need them. Markdown and MDX Cloudflare docs pages are authored in MDX, which is Markdown extended with JSX components. Every page is a .mdx file with a frontmatter block at the top, followed by the body content. Body content The body is standard Markdown. Use it for headings, paragraphs, lists, tables, links, and code: ## A heading A paragraph with a [link](/style-guide/) and `inline code`. - A list item - Another list item Refer to the formatting section for the rules that govern how to write each of these elements. Import components Components add formatting that plain Markdown cannot, such as tabs, asides, and collapsible sections. Import them from ~/components after the frontmatter block, then add them anywhere in the body: --- title: Example page --- import { Aside } from "~/components"; Refer to the components section for the props and requirements of each component. Escape special characters MDX treats {, }, <, and > as syntax. When these characters are part of your content rather than code, wrap them in backticks so they render literally: Set the value to `{"key": "value"}`. Characters inside a fenced code block are already literal and do not need escaping. Code blocks Open a fenced code block with a lowercase language identifier so the code is highlighted correctly. Use txt for generic output that has no language: ```js const value = 1; ``` ```txt Deployment complete. ``` Anchor heading The AnchorHeading component defines headings. Specifically, AnchorHeading performs the following: Generates URL fragments corresponding to headings. Formats URL fragments into compatible syntax. For example, a & is replaced with a -. Creates a button to copy the URL at each fragment. Allows heading fragments to be defined separately from the text of the heading itself. import { AnchorHeading } from "~/components"; Markdown files (including partials) have this behavior by default, applied via rehype plugins. Therefore, the AnchorHeading component is usually only required when writing headings yourself inside components, or when working on non-markdown files. To override the ID given to a heading within Markdown, add an MDX comment at the end of the line: ## foo {/*bar*/} {/* HTML:

foo

*/} :::note The AnchorHeading component emulates the behavior of the rehype-slug and the rehype-autolink-headings. It adds an id based on the output of github-slugger to the heading, as well as adding a button to copy a link to that particular heading. ::: API request import { APIRequest } from "~/components"; Usage import { APIRequest } from "~/components"; Props path required type: string The path for the API endpoint. This can be found in our API documentation, under the name of the endpoint. method required type: "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" The HTTP method to use. parameters type: Record The parameters to substitute - either in the URL path or as query parameters. For example, /zones/{zone_id}/page_shield/scripts can be transformed into /zones/123/page_shield/scripts?direction=asc with the following: parameters={{ zone_id: "123", direction: "asc" }} If not provided, the component will default to an environment variable. For example, {setting_id} will be replaced with $SETTING_ID. json type: Record | Record[] The JSON payload to send. If required properties are missing, the component will throw an error. Functionally, the --json option is equivalent to the --data option in cURL, but handles a few additional headers automatically. form type: Record The FormData payload to send. This field is not currently validated against the schema. code type: object An object of Astro Code props. Refer to the Astro Code component documentation for available props. roles type: string | boolean default: true If set to true, which is the default, all API token roles will show. If set to false, API token roles will not be displayed. If set to a string, the API token roles will be filtered using it as a substring (i.e, roles="domain" to filter out Account API Gateway and only leave Domain API Gateway). Available notifications import { AvailableNotifications } from "~/components"; Notifications import { Code } from " /components" import glossary from "/content/notifications/index.yaml?raw" Badges import { Badge } from "~/components"; Badges are a built-in component provided by Nimbus. Use them to indicate a product is in beta, for example. Component import { Badge } from "~/components"; Sidebar Badges can be added to the sidebar via page frontmatter. --- title: Hello World sidebar: badge: variant: tip text: New --- If you want to add the Beta badge to a product, omit the variant: entry: --- title: Hello World sidebar: badge: text: Beta --- Buttons import { LinkButton } from "~/components"; Get started More information Other stuff Cards import { Render } from "~/components"; Cards are a built-in component provided by Nimbus. Cards import { Card } from "~/components"; Interesting content you want to highlight. List cards import ListCard from "~/components/cf/ListCard.astro"; - foo - bar - baz Link title cards import { LinkTitleCard } from "~/components"; Interesting content you want to highlight. Card icons CfCommand import { Type, MetaInfo } from "~/components"; The CfCommand component documents one Cloudflare CLI command using metadata from the version of cf installed in the cloudflare-docs repository. Import import { CfCommand } from "~/components"; Usage import { CfCommand } from "~/components"; Arguments command is the command without the cf prefix, such as deploy or auth whoami. headingLevel sets the heading level for the command name. CfNamespace import { Type, MetaInfo } from "~/components"; The CfNamespace component documents every visible command in a Cloudflare CLI namespace using metadata from the version of cf installed in the cloudflare-docs repository. Import import { CfNamespace } from "~/components"; Usage import { CfNamespace } from "~/components"; Arguments namespace is the namespace without the cf prefix, such as hyperdrive. headingLevel sets the heading level for each command name. CopyPrompt import { CopyPrompt } from "~/components"; The CopyPrompt component displays a one-line prompt next to a Copy prompt button. Use it when readers can complete a task by pasting a prompt into an AI coding agent, such as a quickstart that an agent can run for them. Import import { CopyPrompt } from "~/components"; Usage import { CopyPrompt } from "~/components"; The prompt displays on a single line and is truncated if it does not fit, but the full text is always copied. Keep prompts short so readers can see what they are copying. For longer prompts, use a code block with txt as the language instead. Props text type: string The prompt to display. Selecting Copy prompt copies this text to the clipboard. CURL The CURL component is used to display a cURL command for making HTTP requests. Import import { CURL } from "~/components"; Usage import { CURL } from "~/components"; Props url required type: string The URL to make the request to. method type: "GET" | "HEAD" | "POST" | "PUT" | "DELETE" | "OPTIONS" | "PATCH" default: "GET" The HTTP method to use for the request. headers type: Record The headers to include in the request. json type: Record | Record[] JSON data to include in the request. form type: Record The FormData payload to send. query type: Record URL query parameters to append to the request URL. code type: object An object of Astro Code props. Refer to the Astro Code component documentation for available props. DashButton import AvailableDashRoutes from "~/components/AvailableDashRoutes.astro"; This component creates a LinkButton that links to a Cloudflare dashboard deeplink. While we recommend the use of DashButton, you can continue to use deeplinks (as a link, without the component), if necessary. :::note[Where routes are stored] The list of available routes are generated by running a script that we manually trigger periodically. The script outputs the available paths in src/content/dash-routes/index.json. The DashButton component then uses those routes to automatically generate the list of buttons on this page. The DashButton will fail to build if you edit the url prop to a route that is not listed in the index.json file. Additionally, each run of the script overwrites the previous /dash-routes/index.json file. If you edit the this file manually, it will be overwritten in the next run of the script. Therefore, only make manual changes to this file if both of the following are true: The link is already live in the dashboard. The name-change is confirmed, and there's no (or little) chance of rollback. ::: Import import { DashButton } from "~/components"; ; Usage Core dashboard import { DashButton } from "~/components"; 1. In the Cloudflare dashboard, go to the **WAF** page. 2. ... Zero Trust dashboard import { DashButton } from "~/components"; 1. Log in to Cloudflare One and go to the **AI controls** page. 2. ... Props url type: string The Cloudflare dashboard deeplink to navigate to. See the below list for available routes. buttonName type: string default: The name of the route. Additional name to override the default name of the route. zeroTrust type: boolean default: false Set to true to use the Zero Trust dashboard routes instead of the Cloudflare dashboard routes. Available routes Descriptions import { Description } from "~/components" Hello, world! Details import { Type, MetaInfo, Render } from "~/components"; When you want to provide additional information in context, but you do not want it to clutter up the more important content, use
to add a collapsible container. import { Details } from "~/components";
Hello, world!
You can specify the default configuration of each instance of the
component (that is, whether it is open or closed by default). import { Details } from "~/components";
Long piece of code example.
Additional guidance Properties header id Adds a specific id to the HTML element open Directory listing import { Render } from "~/components"; Usage import { DirectoryListing } from "~/components";

Default


maxDepth

Descriptions

Button

Props folder type: string The folder path to list contents from. If not provided, defaults to the current page's path. button type: boolean default: false When enabled, displays the listing as a 3-column grid of button-style cards (sorted alphabetically) instead of a bullet list. The cards match the style of our LinkCard component. descriptions type: boolean default: false When enabled, shows the frontmatter description field for each page in the listing. maxDepth type: number default: 1 Controls how many levels of nested pages to display. A value of 1 shows only direct children, while higher values will show deeper nesting levels. tag type: string Optionally, filter the listing to only pages with a specific tag. Associated content types Navigation Example Use the component to add a box around some content. This can be useful when you want to demonstrate or showcase something without it being confused by the surrounding text. import { Example } from "~/components" Hello, world! {/* `title` is an optional string which customizes the title of your example card */} Hello, world! Feature The component lists features available in the product and provides a link button to use the feature. The header parameter supplies the feature name and the href parameter supplies the link to the feature. Text wrapped in the component supplies the description. import { Feature } from "~/components" Hello, world! import { Feature } from "~/components" Hello, world! File tree File tree is a built-in component provided by Nimbus. import { FileTree } from "~/components" - src - docs - style-guide - components - **file-tree.mdx** Glossary definition Use the this component to add extra information to an existing glossary entry. term defines which glossary entry you want to prepend information to, while prepend= adds the extra info. Component import { GlossaryDefinition } from "~/components" Glossary import { Code } from " /components" import glossary from "/content/glossary/style-guide.yaml?raw" Glossary tooltip Use this component to add tooltips to words in your markdown files. The info for the tooltips is pulled in from the glossary yaml file. term specifies which glossary entry you want to pull information from. The text between the opening and closing components is the word or words that you want to define with the glossary entry. Component import { GlossaryTooltip } from "~/components" Hover over me! Glossary import { Code } from " /components" import glossary from "/content/glossary/style-guide.yaml?raw" Glossary Use the glossary definition shortcode to render the defined glossary definition. Additionally, you can include a prepend value to add words to the start of the definition. Create the glossary entries in a file dedicated to your product. These YAML files live in /src/content/glossary/.yaml Component import { Glossary } from "~/components" Glossary import { Code } from " /components" import glossary from "/content/glossary/style-guide.yaml?raw" Icons import { Render } from "~/components"; There are two icon components which pull from two different icon sets. Icon The Icon component from Nimbus is available as a standalone component. Primarily, this is used for Cloudflare product icons which are stored in /src/icons/*.svg. import { Icon } from "~/components"; Card and LinkCard Components like Card and LinkCard accept a plain icon string prop — any iconify icon name. import { Card, LinkCard } from "~/components"; Content authored before the Nimbus migration may still use Starlight-style icon names (for example icon="seti:shell"). These are automatically mapped to an equivalent iconify icon at build time. New content should use iconify names directly. Icon library Components import { Details, Example } from "~/components"; When you are contributing to the Cloudflare Docs, you can use our custom components to add additional formatting, such as buttons, tabs, and collapsible sections. This guide shows you the basics of importing and adding a component to a page. Refer to each component page in this Style Guide to learn the specific props and requirements for each. Our components are based on Astro components and are written in MDX, an extended version of Markdown. Learn more about the Cloudflare Docs framework. Add a component to a page To add a component to a page: Import the component to the page by adding this text directly below the frontmatter: import { COMPONENT_NAME } from "~/components"; ; For example, if you were to add the DashButton component to the Images getting started page, the top of the MDX file corresponding to that page would look like the following: --- pcx_content_type: get-started title: Getting started products: - images sidebar: order: 2 --- import { DashButton } from "~/components"; ; Page-specific wrapper components or one-off components do not need to be added to the barrel — import them via a deep path: import BaseSchemaProperties from "~/components/BaseSchemaProperties.astro"; Add the component to the page by adding this text anywhere on the page you want the component to appear: For example, if you were to add the DashButton component to some steps in the Images getting started page, here is how the MDX file would look: 1. In the Cloudflare dashboard, go to the **Transformations** page. 2. Go to the specific zone where you want to enable transformations. ![DashButton component example](~/assets/images/style-guide/ui-elements/dashbutton-example.png) Choose the right component To choose the right component for your use case, browse this table which contains our most commonly used components and a visual example of each. For full documentation on all available components and their use cases, browse the individual component pages in this Style Guide. Component Description & visual example APIRequest Styled API request block. Generate executable cURL API commands with the required API token permissions. Badge Small descriptive pill. Label content with status, version, category, or other short metadata. DashButton Dashboard deep-link button. Directly link users from documentation into a specific, relevant section of the Cloudflare Dashboard. Details Click-to-expand content block. Hide non-essential, complex, or advanced technical content, allowing users to expand the section when needed. DirectoryListing Auto-generated sub-page list. Automatically generate a navigable list of links to sub-pages within a specified documentation folder path. Feature Product feature list item. Highlight a product feature with a description and a direct link button. GlossaryTooltip Hover-activated glossary popup. Provide non-disruptive, hover-activated definitions for technical terms pulled from the documentation glossary. LinkCard Navigational cards. Present related tutorials, concepts, or guides in a visually engaging format. PackageManagers Command switcher tabs. Display equivalent installation or execution commands for different package managers. Plan Product plan availability badge. Show the plan required for a product or specific feature. RelatedProduct Formatted product reference. Visually highlight and link to a specific, complementary Cloudflare product, also featuring the product's logo. ResourcesBySelector Filterable code example library. Pull and display lists of code examples and resources based on content type or products. Stream Embeddable video player. Display a video player optimized for Cloudflare Stream. Tabs and TabItem Switchable content tabs. Allow easy switching between content views for different code languages or configuration methods. Type and MetaInfo Pill-shaped data type badge and metadata annotation about a field or property. Type indicates API parameter data types ( String, Integer) and MetaInfo indicates metadata constraints ( Required, Optional, Read-only). WranglerConfig Tabbed Wrangler config display. Show Wrangler configuration files (JSONC and TOML) and bindings with automatic format switching. YouTube Embeddable video player. Embeds a YouTube video player with a specified video ID. Inline badge :::caution[Recommendation: Avoid inline badges] Our current recommendation is to avoid inline badges, since they may hurt readability. Guidelines: Mention beta/alpha/early access in the feature's main documentation page (use the component for this purpose). If an additional reference is needed in the middle of the text, use "(beta)", with no special formatting, after the feature name. For instructions related to the feature (such as instructions on turning the feature on or off), you may mention again it's in beta, and also include "(beta)" in the side nav. ::: Component To adopt this styling in a React component, apply the sl-badge class to a span element. import { InlineBadge } from '~/components'; ### Alpha ### Beta ### Deprecated ### Early Access ### Legacy ### Default Inputs Either preset or text and variant must be specified. Presets alpha Text: Alpha Variant success beta Text: Beta Variant caution deprecated Text: Deprecated Variant danger early-access Text: Early Access Variant note legacy Text: Legacy Variant danger Text Any string. Variant note Color: Blue tip Color: Purple danger Color: Red caution Color: Orange success Color: Green Link cards import { CardGrid, LinkCard } from "~/components" {[...Array(4).keys()].map(() => ( ))} List tutorials import { ListTutorials } from "~/components"; Associated content types Tutorial Markdown This component uses marked to render CommonMark and various other Markdown flavours. :::caution This component can not use MDX or Astro features, such as optimised images in the assets directory. Headings should not be used with this component, as they will not receive an id, copyable link or appear in the table of contents. Code blocks should not be used with this component, as they will not receive syntax highlighting or a copy to clipboard button. ::: import { Markdown } from "~/components"; Example for variables in partials If you have a variable that needs to be formatted in any special way (for example, it needs to be a URL, an unordered list, or something else), you can wrap the variable with the markdown component in your partial file. For example: Note that you need to wrap your variable in curly braces, as well as use text= or this will not work. Multi-line strings The Markdown component uses the dedent library to remove indentation from multi-line strings. This is because the CommonMark spec treats indented text as code blocks, unlike MDX. import { Markdown } from "~/components"; <> Package Managers This component is based on the Nimbus package manager component and adds repository-specific support for global installs and reviewed Cloudflare CLI alternatives. import { PackageManagers } from "~/components"; Use global only for packages designed to be installed globally. Use cfCommand only for a reviewed, single-line Cloudflare CLI equivalent of a Wrangler execution command. The value must begin with cf . Supplying this prop displays the shared CLI selector. Pages build preset import { PagesBuildPreset } from "~/components"; Plan The plan component lets you define what type of plan your product needs. Use it in the main Overview page of your product, or in a page where you need to talk about a specific feature with additional requirements. Use , choosing the type that matches your product's availability. Refer to the examples below for more information. import { Plan } from "~/components" Product availability text The ProductAvailabilityText component dynamically renders a product's lifecycle status (such as "Beta" or "Alpha") inline with the product name. It renders nothing for generally available (GA) products, so it is safe to leave in place as a product matures. The product prop must match a file in src/content/directory/. import { ProductAvailabilityText } from "~/components"; Cloud Connector allows you to route matching traffic to a public cloud provider. Props Prop Type Required Default Description product string Yes — Product slug matching a file in src/content/directory/. parentheses string No "true" When "true", wraps the output in parentheses (for example, (Beta)). Set to "false" for the raw text. Behavior If the product availability is GA, the component renders nothing. If the product or its availability data is not found, the component renders nothing (and logs a warning at build time). Product changelog This component can be used to display entries from the changelog for a given product or product area. Import import { ProductChangelog } from "~/components"; Usage import { ProductChangelog } from "~/components"; Props The product and area props cannot be used at the same time. product type: string The name of the product. area type: string The name of the product area. hideEntry type: string The id of a specific entry to hide. publish_future_dated_entry type: boolean default: false Set to true to show future-dated entries (used for WAF scheduled changelogs). numberOfEntries type: number Limits the number of entries shown. Public stats import { Render } from "~/components"; Refer to the examples below for more information. import { PublicStats } from "~/components"; Cloudflare has data centers in . Our network has . Cloudflare also has . :::note If you need more stats or to update these stats, submit a pull request to update PublicStats.astro ::: Associated content types The PublicStats component is commonly used on the following type of pages: Overview Reference Architecture Reference Architecture Diagrams Related product The component lists products related or connected to the current product. The header parameter is the name of the product and the href parameter links to the product. The product parameter defines the product icon to use based on the slugified name. Use in Overview pages. import { RelatedProduct } from "~/components"; Store large amounts of unstructured data without the costly egress bandwidth fees associated with typical cloud storage services. A suite of products tailored to your image-processing needs. Render import { Code, Details, Type, MetaInfo } from "~/components"; The Render component allows us to include a "partial", a reusable Markdown snippet, onto a page. It also accepts parameters that can be used as variables within the partial, so that even content which needs slight differences between usages can be turned into a partial. Component import { Render } from "~/components"; Inputs file This should be the name of the partial, without the containing directory or file extension. For example, /partials/style-guide/hello.mdx would be file="hello". product This should be the folder within src/partials. params If you wish to substitute values inside your partial, you can use pass params which can be referenced in your partial. Refer to properties. Properties Defining expected properties in frontmatter Anything defined in the params property of the Render component is available inside the partial, using JavaScript expressions. To protect against required properties being missed, any partial that relies on params should also define params in the partial's frontmatter. This should be an array of strings, matching the property names you expect. --- params: - product --- :::note Partials must use params only for simple value substitution (for example, {props.name}). Do not use conditional or branching logic (such as &&, ternary ? :, or comparisons like ===) inside a partial. If content needs to differ between call sites, create a separate partial for each variation instead. ::: For each of the below examples, you can open the dropdown to view the partial's content. Properties as a plain string The below example would render Hello, world!. import simpleRaw from "~/content/partials/style-guide/simple-props.mdx?raw"; import { Render } from "~/components"; Properties in Markdown syntax When using JavaScript expressions, you are now "inside JSX" and cannot use traditional Markdown syntax. Similarly, you cannot use a JavaScript expression inside Markdown syntax. Ideally, you should not use Markdown syntax, such as **strong** or [text](link), with properties. If using JSX is not feasible, there is a Markdown component that will take a text property. The MDX documentation includes a mapping of common Markdown syntax to their equivalent JSX elements. Strong import strongRaw from "~/content/partials/style-guide/strong-in-props.mdx?raw"; import { Render } from "~/components"; Links import linkRaw from "~/content/partials/style-guide/link-in-props.mdx?raw"; import { Render } from "~/components"; Images import imageRaw from "~/content/partials/style-guide/image-in-props.mdx?raw"; import { Render } from "~/components"; Code blocks import codeRaw from "~/content/partials/style-guide/code-in-props.mdx?raw"; import { Render } from "~/components"; Resources by selector import { Type, MetaInfo } from "~/components"; The ResourcesBySelector component allows you to pull in documentation resources based on the pcx_content_type and products frontmatter properties. Component import { ResourcesBySelector } from "~/components"; Inputs directory The directory to search for resources in, relative to src/content/docs/. For example, for Workers tutorials, directory="workers/tutorials/". filterables An array of frontmatter properties to show in the frontend filter dropdown. For example, filterables={["products"]} will allow users to filter based on each pages' products frontmatter. types An array of pcx_content_type values to filter which content gets pulled into the component. For example, types={["example"]}. products An array of products values to filter which content gets pulled into the component. For example, products={["D1"]}. showDescriptions If set to false, will only show the titles of associated pages, not the showDescriptions showLastUpdated If set to true, will add the last updated date, which is added in the updated frontmatter value. RSSButton import { RSSButton } from "~/components";
Props text type: string default: "Subscribe to RSS" The text to display in the button. icon type: string default: "rss" The icon to display next to the text. Renders via the Nimbus Icon component; accepts any iconify icon name (for example, ph:rss-simple). The default "rss" maps to ph:rss-simple. changelog or href You must provide either changelog or href, but not both: changelog type: string The name of the changelog to link to. This will be transformed into a lowercase, hyphen-separated string and used to construct the RSS feed URL in the format /changelog/rss/{changelog}.xml. href type: string A custom URL to link to. Use this when you need to link to an RSS feed that doesn't follow the standard changelog URL pattern. Rule ID import { RuleID } from "~/components" Steps import { Steps } from "~/components" 1. Import the `Steps` components 2. Wrap your numbered list in the `Steps` components 3. Done! Stream import { Stream } from "~/components"; Usage import { Stream } from "~/components"; Props id required type: string The ID of the Stream video. title required type: string The title of the Stream video. thumbnail type: string Either a timestamp (i.e 2.5s or 1m35s) or a URL to an image. chapters type: Record Optional chapters displayed as cards below the video. expandChapters type: boolean default: false If chapters is present, is passed through to the open property of the Details component. showMoreVideos type: boolean default: true Whether to show the "Watch more videos on our Developer Channel" link below the video. file type: string If file is provided, the id, title, thumbnail and chapters properties cannot be used and are instead retrieved from the YAML file in the stream collection. Subtract IP calculator import { SubtractIPCalculator } from "~/components"; Import import { SubtractIPCalculator } from "~/components"; Usage import { SubtractIPCalculator } from "~/components"; Props defaults type: object An optional object containing base ( string) and subtract ( string[]) properties, to set default inputs. example: import { SubtractIPCalculator } from "~/components"; Tabs import { Tabs, TabItem, Render } from "~/components"; This component can help you create a tabbed interface to show related information more efficiently. Use it when there are different ways of getting the same thing done: Dashboard / API / Terraform Different code syntax styles Account-level vs zone-level navigation GRE / IPsec tunnels Additional guidance import { Tabs, TabItem } from "~/components"; Sirius, Vega, Betelgeuse Io, Europa, Ganymede Tab icons Synchronize Tabs If you have tabs that follow a particular pattern (Dashboard / API / Terraform), add a syncKey parameter that includes a string value. We use the following syncKey values in our docs: dashPlusAPI: Dashboard / API / Terraform workersExamples: For different code language tabs in the Workers docs (JavaScript, TypeScript, Python, Rust) Example import { Tabs, TabItem } from "~/components"; Dash instructions API instructions Will synchronize with: Dash instructions API instructions Type highlighting import { Type } from "~/components"; MetaInfo import { MetaInfo } from "~/components"; Combined example import { Type, MetaInfo } from "~/components"; - `name` - The name of your service. - `local` - If the service should run locally or not. TypeScript example The TypeScriptExample component uses ts-blank-space to remove TypeScript-specific syntax from your example and provide a JavaScript tab. This reduces maintenance burden by only having a single example to maintain. :::note Some TypeScript syntax influences runtime behaviour, and cannot be stripped. Please refer to the Unsupported Syntax section of the project's README. ::: :::caution Code blocks are typically configured with options on the opening fence, like so: ```ts collapse={1-2} // ... ``` These cannot be extracted by TypeScriptExample so they must be moved to the code prop. ```ts // ... ``` ::: Component import { TypeScriptExample } from "~/components"; ```ts // comment to demonstrate // collapsible sections interface Environment { KV: KVNamespace; } export default { async fetch(req, env, ctx): Promise { if (req !== "POST") { return new Response("Method Not Allowed", { status: 405, headers: { "Allow": "POST" } }); } await env.KV.put("foo", "bar"); return new Response(); } } satisfies ExportedHandler ``` Props filename type: string An optional filename, ending in .ts. .ts will be replaced by .js for the JavaScript tab. playground type: boolean If set to true, a Run Worker in Playground button will appear on the JavaScript tab. code type: object Props to pass to the Astro Code component. These props will apply to both code blocks and so options like collapse may not work as expected, as lines may be removed from the TypeScript code. Usage import ComponentsUsage from "~/components/cf/ComponentsUsage.astro"; This page contains a breakdown of each component and the pages where they are used. Width This component can be used to constrain the width of content, such as text or images. Import import { Width } from "~/components"; Usage import { Width } from "~/components"; This content will take up 75% of the container width This content will take up 50% of the container width This content will take up 25% of the container width This content will take up 25% of the container width and be centered Props size required type: "large" | "medium" | "small" Controls the width of the container: large: 75% of container width medium: 50% of container width small: 25% of container width center type: boolean Whether to horizontally center the content. WranglerCommand import { Type, MetaInfo } from "~/components"; The WranglerCommand component documents the available options for a given command. This is generated using the Wrangler version in the cloudflare-docs repository. Import import { WranglerCommand } from "~/components"; Usage import { WranglerCommand } from "~/components"; With ExtraFlagDetails You can add or replace help text for specific flags using the ExtraFlagDetails component: import { WranglerCommand } from "~/components"; import ExtraFlagDetails from "~/components/cf/ExtraFlagDetails.astro"; Additional details about the dry-run flag that will be appended to the original help text. Here is a [link](https://cloudflare.com) for more information. Custom help text that completely replaces the original description for this flag. Arguments command The name of the command, i.e d1 execute. headingLevel The heading level that the command name should be added at on the page, i.e 2 for a h2. description A description to render below the command heading. If not set, defaults to the value specified in the Wrangler help API. cfCommand One or more reviewed Cloudflare CLI equivalents without the cf prefix. Supplying this prop displays the shared CLI selector. Explain partial or non-equivalent workflows in the surrounding page content. includeHiddenCf Allows explicitly reviewed cfCommand values that the installed Cloudflare CLI marks as hidden. WranglerConfig This component can be used to automatically generate a jsonc version of the toml file (or vice versa) of the Cloudflare Wrangler configuration file. Import import { WranglerConfig } from "~/components"; Usage import { WranglerConfig } from "~/components"; ```toml [[d1_databases]] binding = "DB" # available in your Worker on env.DB database_name = "prod-d1-tutorial" database_id = "" ``` Cloudflare CLI configuration Use cfConfig to provide a reviewed cloudflare.config.ts equivalent. Supplying this prop displays the shared CLI selector. import { WranglerConfig } from "~/components"; ```jsonc { "name": "my-worker" } ``` Compatibility date You should generally use $today for the compatibility_date value for new projects. This magic string is automatically replaced with the current date at build time, ensuring documentation always suggests the latest date. When $today is used, the component also automatically injects a comment above the compatibility_date line (for example, # Set this to today's date in TOML and // Set this to today's date in JSONC) so that readers know to keep the value current. If you need to specify a fixed date, you can do so as well, but you may miss out on the latest features and performance improvements. You can disable specific features by using compatibility flags. import { WranglerConfig } from "~/components"; ```jsonc { "name": "my-worker", "compatibility_date": "$today" } ``` Minimum compatibility dates Some features require a minimum compatibility date. When documenting these features, use a :::note component to communicate the requirement clearly on the docs page: :::note This feature requires a `compatibility_date` of `2024-09-23` or later. ::: :::note This feature requires a compatibility_date of 2024-09-23 or later. ::: The removeSchema prop can be used to remove the $schema reference from the generated JSON file. This can be useful if you want to add snippets of configuration files that are easier to copy paste, and are providing toml as the source config format. If you provide jsonc as the source config format, the removeSchema prop will be ignored. import { WranglerConfig } from "~/components"; ```toml [[d1_databases]] binding = "DB" # available in your Worker on env.DB database_name = "prod-d1-tutorial" database_id = "" ``` WranglerNamespace import { Type, MetaInfo } from "~/components"; The WranglerNamespace component documents the available commands for a given namespace. This is generated using the Wrangler version in the cloudflare-docs repository. Import import { WranglerNamespace } from "~/components"; Usage import { WranglerNamespace } from "~/components"; Arguments namespace The namespace to pull the related commands from ( d1, hyperdrive). headingLevel The heading level that the commands should be added at on the page, i.e 2 for h2. cfNamespace A reviewed Cloudflare CLI namespace without the cf prefix. Supplying this prop displays one shared CLI selector for the namespace. Explain differences between the command families in the surrounding page content. YouTube import { YouTube } from "~/components" import { YouTube } from "~/components" Banner import { Steps, FileTree } from "~/components"; One of the fields you can add to the Frontmatter is banner. It displays a prominent section at the top of the page and supports the use of HTML for links and formatting. Only use it to alert about disruptive situations and take note to remove it when applicable. Example --- title: Banner description: How to display a banner at the top of the page and when to use it. banner: content: Do not use banners in the Frontmatter unless a change will cause customer application to break. --- Styles / Types Note The note banner is used to alert about important information. --- title: Banner description: How to display a banner at the top of the page and when to use it. banner: content: Ensure you read this! type: note --- Tip The tip banner is used to alert about important suggestions. --- title: Banner description: How to display a banner at the top of the page and when to use it. banner: content: Consider this alternative! type: tip --- Caution The caution banner is used to warn readers of upcoming disruptive changes. --- title: Banner description: How to display a banner at the top of the page and when to use it. banner: content: This is deprecated and will break on 1970-01-01! type: caution --- Danger The danger banner is used to alert about errors. --- title: Banner description: How to display a banner at the top of the page and when to use it. banner: content: This has been removed! type: danger --- Default The default banner is used in all other circumstances. --- title: Banner description: How to display a banner at the top of the page and when to use it. banner: content: Do not use banners in the Frontmatter unless a change will cause customer application to break. --- Custom properties import { Type, MetaInfo } from " /components"; import BaseSchemaProperties from "/components/BaseSchemaProperties.astro"; We have added specific custom frontmatter properties to meet specific needs. :::note The description field is a Nimbus built-in, not a custom property, but it is required for all pages with a pcx_content_type. For writing guidance, refer to Writing a description. ::: Properties Frontmatter Frontmatter contains the metadata for a page, such as the title. It is written as YAML, between ---, at the top of the page. For example: --- title: Create a Cloudflare Tunnel pcx_content_type: how-to products: - cloudflare-tunnel description: Set the required and optional frontmatter fields that carry a page's metadata, such as title, description, and pcx_content_type. sidebar: order: 2 --- For more information on the available fields, refer to Nimbus's documentation. Required fields Every page with a pcx_content_type must include: Field Description title The page title. Plain text. pcx_content_type The content type of the page. Refer to content types. description A 1-2 sentence summary used for the tag. Refer to writing a description. Writing a description The description field populates the tag in the HTML head. This is the single most important metadata field for search engines, AI crawlers, and llms.txt consumers when deciding whether to surface or cite a page. A strong description: Is 1-2 self-contained sentences (aim for 50-160 characters). Names the product or feature. States what the page helps the reader do or understand. Works as a standalone answer snippet when extracted from the page. Do not start with generic openers like "This page describes...", "Learn more about...", or "This document explains...". These waste the most valuable metadata space without adding information. The existing summary field remains useful for the on-page experience but is secondary to description for AI and search purposes. Examples description: Set the required and optional frontmatter fields that carry a page's metadata, such as title, description, and pcx_content_type. description: Set the required and optional frontmatter fields that carry a page's metadata, such as title, description, and pcx_content_type. description: Set the required and optional frontmatter fields that carry a page's metadata, such as title, description, and pcx_content_type. description: Set the required and optional frontmatter fields that carry a page's metadata, such as title, description, and pcx_content_type. Optional fields For optional fields such as sidebar, tags, products, difficulty, and reviewed, refer to Custom properties. For more information on the available fields, refer to Nimbus's documentation. Sidebar import { Steps, FileTree } from "~/components"; Labels Labels are controlled by frontmatter properties on a given page, which vary depending on if you are configuring a group or a link. Links In order of precedence: sidebar.label title On an index page Index page labels default to Overview if sidebar.label is not defined. title is not taken into consideration due to title being used in group labelling. Groups In order of precedence: sidebar.group.label title Example For example, given the following pages: --- title: Bar sidebar: label: IndexTitle group: label: GroupTitle --- --- title: Baz sidebar: label: PageTitle --- The sidebar structure will look like: GroupTitle IndexTitle PageTitle If we remove the sidebar property from both, it will now look like this: Bar Overview Baz Ordering Both links and groups use the sidebar.order frontmatter property to configure their ordering, where groups are ordered based on the index page's order. If sidebar.order is not specified, it will fallback to alphabetical ordering. For example, given the following pages: --- title: Alpha sidebar: order: 3 --- --- title: Beta sidebar: order: 2 --- The sidebar structure will look like: Beta ... Alpha ... If we remove the sidebar property from both, it will now look like this: Alpha ... Beta ... Hiding pages There are three properties that can be used for hiding pages from the sidebar. Hiding individual pages hidden This property should only be used when the page is not an index page for a group. --- title: Placeholder sidebar: hidden: true --- group.hideIndex Since index pages are relied on to configure the label and sort order of groups, we have a special property that still makes the page available to our sidebar component and allows us to remove it after labelling and ordering groups. --- title: Placeholder sidebar: group: hideIndex: true --- import { DirectoryListing } from "~/components"; :::note Since these pages are still accessible via other links and directly navigating to the URL, always include a DirectoryListing component within the page content. ::: Hiding child pages of a group To make a group render as if it was a single page, which links to the index page, use the top-level hideChildren property. Badges Links To specify a badge next to the link, use the sidebar.badge property. --- title: Example sidebar: badge: New! --- Examples Example [New!] Groups To specify a badge next to the group label, use the sidebar.group.badge inside the group's index.mdx frontmatter. --- title: Examples sidebar: group: badge: New! --- Examples [New!] Example Automatic "Beta" badges A "Beta" badge is automatically added to sidebar links and groups whose URL matches a directory entry with a "Beta" availability status. This badge is not controlled by frontmatter — it is derived from the product availability data associated with the entry in src/content/directory/. File conventions Our docs have a few conventions around files. Naming When creating new files, follow specific conventions for your naming. Filenames should: Semantically communicate the purpose of the file Be lowercased Use dashes between words /src/content/docs/fundamentals/concepts/what-is-cloudflare.mdx /src/assets/images/api-shield/api-shield-call-sequence.png /src/content/docs/fundamentals/concepts/What is Cloudflare.mdx /src/content/docs/fundamentals/concepts/What-is-Cloudflare.mdx /src/assets/images/api-shield/API_Image_1.png These conventions are important for user readability, SEO conventions, and making sure our GitHub actions do not break. Folders Each folder should have a file named index.mdx. /src/content/docs/fundamentals/concepts/index.mdx The content at /src/content/docs/fundamentals/concepts/index.mdx will be rendered at https://developers.cloudflare.com/fundamentals/concepts/. Content files Add regular content files to the /src/content/docs/{product_folder}/ directory. /src/content/docs/fundamentals/concepts/what-is-cloudflare.mdx Image files Add image files to the /src/assets/images/{product_folder}/ directory. /src/assets/images/api-shield/api-shield-call-sequence.png Product content import { DirectoryListing } from "~/components"; This section is the planning layer of the style guide. It tells you what kind of page to write, where it lives, and what parts it is built from. The three areas follow the order you meet them when you plan a page. Once the page is planned, Style and grammar covers how to write it in the house voice. What to write Content types catalog the defined page shapes and help you choose the right one. Every type documents how it is structured, scaffolded, and maintained. How to structure it Information architecture governs on-page section order and the folder shape a reader navigates. File conventions governs the repo file, folder, and image naming a builder works with. The parts a page is built from Component attributes covers the content-strategy parts of a page, such as introductions, prerequisites, and next steps. Formatting and component mechanics live in their own sibling sections, linked from each part. All pages in this section Information architecture Every product's documentation is built from the same core set of sections, so a reader who knows one product's docs can predict where to find things in another. Consistency is enforced, not optional. A product may add sections that it genuinely needs, but those additions are additive: a product never renames, restructures, or redefines a core section because a different shape "makes more sense" for it. Keep the core the same, and grow around it. This page defines the shared core at the section (folder) level. To choose the type of an individual page, refer to Content types. Required sections Every product includes at least these two pages, from its first release: Overview, which orients a new reader and routes them onward. Get started, which takes a new user from nothing to a first working result. Core sections Beyond the required pair, use these standard sections whenever your product has the content they describe. Use the standard name so that readers and agents navigate every product's docs the same way. Section What it contains Related content type Overview Orients a new reader to the product and routes them onward. Required. Overview Get started The shortest path from nothing to a first working result. Required. Get started Concepts What the product's key ideas are and why they work the way they do. Concept Features Groups the task and settings content for a major feature of the product. How to Guides Task-focused pages for completing one specific job. How to Tutorials End-to-end lessons where the reader builds a real project. Tutorial Examples Complete, runnable samples that show how something is done. None Configuration The settings, values, and options for a configuration-intensive feature. Configuration Reference Complete, neutral lookup details such as parameters, values, and options. Reference API The product's API documentation and command guidance. API content strategy Models The available models and their details, for AI products. Reference Observability Testing, metrics, analytics, and local development. None Best practices Recommended patterns and guidance for using the product well. None Platform Product-wide pages such as pricing, limits, changelog, betas, and known issues. Changelog Glossary The product's defined terms. Glossary Structure and ordering rules Keep the Overview at the product root index.mdx. Make every other core section a folder, even when it currently holds a single page. A lone get-started.mdx becomes a get-started/ folder. Place the core folders before any product-specific folders, in the order given under Core sections. Give every product a Platform folder that holds at least one page, so this section is present consistently rather than only on some products. Name any product-specific folder uniquely and clearly. A product-specific folder is additive: it adds to the core, and it never replaces or reshapes a core section. Add sections freely, but do not edit the core. If a core section does not fit your product as written, raise it through docs governance rather than renaming or restructuring it locally. Bring an existing product into line Audit the product against the core, then close the gaps: Rename non-standard folders to the standard names. For example, rename a getting-started folder to get-started, and rename a how-to folder to the standard guides. Fold loose files into their core folder. A single concepts.mdx becomes a concepts/ folder. Pull core content up to the top level when it sits inside platform/ but belongs to a core section. Create the core sections your product is missing. Keep useful product-specific folders, and confirm each one is uniquely named and additive. Product categories The core applies across every product category, including Compute, Storage, AI, Media, and the vertical products. A category can share additional sections that its products all need. For example, AI products commonly add a Models section. As a product matures it keeps the same core and grows by adding sections, not by reshaping the core. Dynamic lists Dynamic lists automatically add or remove elements based on set criteria. Used in When at all possible, Cloudflare seeks to avoid creating static representations of dynamic options. Structure Potential examples include: Exhaustive listing of fields Replicating API content in developer docs Maintaining lists of potential options in the UI (i.e., Alert types) Verified Bots The preferred approach would be speak more generally to the categories or specific, high-value fields. Examples A code sample or line of text that shows the specific structure of a request/response, input/output, or value for UI/API elements :::note If you are unsure about when to categorize something as an example or tutorial, remember: Examples are a component attribute and are typically a snippet of code a user might copy and paste to run a task. Examples should not have multiple steps. A tutorial might contain an example, but an example will not contain a tutorial. Tutorials are a content type, typically longer form, and contain multiple steps to help users connect products to real-world scenarios. ::: Used in Tutorial, How to, Reference Structure Context Explain what the code sample does in a short sentence. Code blocks or snippets These could include: Example requests and responses Example inputs and outputs Field values for UI and/or API Additional information Code block guidelines Requests/feedback https://github.com/cloudflare/cloudflare-docs/issues/150 Glossary entry import { GlossaryDefinition, GlossaryTooltip } from "~/components"; Definition A single term and corresponding definition in the glossary. Used in Glossary, documentation pages, tooltips. Structure Data The data underlying our glossary lives with YAML files in the /src/content/glossary/* folder. Each file should be structured similar to the following: --- productName: DNS entries: - term: active zone general_definition: |- a DNS zone that is active on Cloudflare requires changing its nameservers to Cloudflare's for management. associated_products: - Cloudflare One - term: apex domain general_definition: |- apex domain is used to refer to a domain that does not contain a subdomain part, such as `example.com` (without `www.`). It is also known as "root domain" or "naked domain". - term: DNS over HTTPS general_definition: |- DNS over HTTPS (DoH) is a standard for encrypting DNS traffic, preventing tracking and spoofing of DNS queries. associated_products: - 1.1.1.1 - Cloudflare One - term: DNS over TLS general_definition: |- DNS over TLS (DoT) is a standard for encrypting DNS traffic using its own port (853) and TLS encryption. associated_products: - 1.1.1.1 - Cloudflare One Relevant values include the following: productName string required Core product associated with this file. Should always match the same formatting / styling used in associated_products. entries object required term string required The glossary term itself. general_definition string required Definition of the term. Should be general enough to apply to multiple products. Should also start with a lowercase letter unless starting with a proper noun. associated_products array optional If the term is associated with other products. Any names used should correspond to the productName of that associated file. Usage Because of the structured data associated with our glossaries, we can pull these terms into multiple places. Product-level glossary A product-level glossary includes all terms associated with a particular product, which will pull in terms directly in that product's glossary file and any terms that include the product in its associated_products. --- title: Glossary pcx_content_type: glossary --- import { Glossary } from "~/components"; Review the definitions for terms used across Cloudflare's DNS documentation. Glossary definition Pull glossary definitions directly into your Markdown by using the component. Is a quoted definition that comes from: Properties are: term string required Should match a term within an existing glossary YAML file. prepend string optional Text to add before a definition. Glossary tooltip Pull component definitions into a focusable tooltip for a specific phrase by using the component. Here's a tooltip example. Here's a tooltip example. Properties are: term string required Should match a term within an existing glossary YAML file. prepend string optional Text to add before a definition. link string optional Wraps the inner text in a markdown link, similar to normal markdown formatting. Because of space limitations, the tooltip will always default to the short definition of a term, meaning the definition text before the first line break. Images and diagrams Images help a reader see a tool, a process, or an architecture. This page covers three: screenshots, diagrams, and reference diagrams. Because images cost more to maintain than text, use them intentionally. Screenshots A screenshot is a picture of a software tool, in this case usually the Cloudflare dashboard. We only recommend screenshots in specific scenarios, as they have a higher maintenance cost than other types of content. When to use Use screenshots sparingly and intentionally. For example, it is appropriate to use a screenshot when the task is simple but often confuses readers or is hard to describe with words alone. A canonical example is Find account and zone ID because: It is a high driver of SEO traffic to our Community. We tried explaining with words alone and that did not solve the confusion. It is a task specifically related to new users, who are less familiar with Cloudflare concepts or navigation patterns. :::note Use screenshots liberally in Changelog entries, because this content type is an accepted point-in-time reference and it is okay for these screenshots to be outdated. ::: Guidelines Screenshots should: Maintain the original aspect-lock ratio. Keep resolution at 72dpi. Keep width at 500-600 pixels. Avoid sharing sensitive information (you may need to edit the underlying HTML in your browser). Avoid including visuals that change frequently, such as sidebar navigation. Have descriptive alt text. Usage ![Alt text](~/assets/images/$PRODUCT_NAME/$IMAGE_NAME.png) Add screenshots to the corresponding $PRODUCT_NAME folder under /src/assets/images/. You may want to add subfolders for organizational purposes. Maintenance We avoid screenshots without a clear purpose because they are difficult to maintain. This is because: The UI might change and our team might not know. Even if you do know what changed, it is difficult to find which screenshots reference a particular UI flow. If something changes, you need to fully re-take the screenshot to replace it. This could involve adding fake data or hiding sensitive information. For more details on how we approach this maintenance, refer to Image maintenance. Diagrams Diagrams are visualizations that depict a process, architecture, or some other form of technology. They explain complex topics in a compelling way and help a reader visualize a specific solution, process, or interaction between products. Diagrams are used in all content types. We recommend either SVG files or Mermaid diagrams. SVG diagrams Use SVG files instead of PNG or JPEG because SVG scales well when a reader zooms in. Use clear and straightforward alt text with your SVG for use by screen readers. We optimize SVG files with a recurring script in our repo. Format an SVG like this: ![Alt text](/link/to/image.svg "Caption to go under the image") For example: ![A simple flow diagram shows interactions between important elements of the design.](~/assets/images/firewall/simple-flow.png "An example flow diagram") Mermaid diagrams Use Mermaid diagrams to illustrate product or process flows. If they work for your use case, Mermaid diagrams are preferable to SVG files because they are more easily searchable and changeable. Our Mermaid diagrams are based on rehype-mermaid and mermaid. Format a Mermaid diagram like this: ```mermaid flowchart LR accTitle: Tunnels diagram accDescr: The example in this diagram has three tunnel routes. Tunnels 1 and 2 have top priority and Tunnel 3 is secondary. subgraph Cloudflare direction LR B[Cloudflare
data center] C[Cloudflare
data center] D[Cloudflare
data center] end A((User)) --> Cloudflare --- E[Anycast IP] E[Anycast IP] --> F[/Tunnel 1 /
priority 1/] --> I{{Customer
data center/
network 1}} E[Anycast IP] --> G[/Tunnel 2 /
priority 1/] --> J{{Customer
data center/
network 2}} E[Anycast IP] --> H[/Tunnel 3 /
priority 2/] --> K{{Customer
data center/
network 3}} ``` For example, this renders as: flowchart LR accTitle: Tunnels diagram accDescr: The example in this diagram has three tunnel routes. Tunnels 1 and 2 have top priority and Tunnel 3 is secondary. subgraph Cloudflare direction LR B[Cloudflare
data center] C[Cloudflare
data center] D[Cloudflare
data center] end A((User)) --> Cloudflare --- E[Anycast IP] E[Anycast IP] --> F[/Tunnel 1 /
priority 1/] --> I{{Customer
data center/
network 1}} E[Anycast IP] --> G[/Tunnel 2 /
priority 1/] --> J{{Customer
data center/
network 2}} E[Anycast IP] --> H[/Tunnel 3 /
priority 2/] --> K{{Customer
data center/
network 3}} Reference diagram A single diagram that portrays all or part of Cloudflare's platform and how Cloudflare would align with a customer's infrastructure or use case. Used in: Reference architecture, Reference architecture diagram Show a complete Cloudflare architecture aligned with a specific infrastructure or use case. Whenever possible, the image should be an SVG. For example: Note: Labels in this image may reflect a previous product name. Component attributes import { DirectoryListing } from "~/components"; Component attributes are the content-strategy parts a page is built from. Each page here covers one part: what it is, when to use it, and how to structure it. Formatting and component mechanics live in their own sections, linked from each part. Moved pages Some parts have merged into a single page, and others now live with the formatting guidance they belong to: Context, Introduction, and Intended audience are now in Introductions. Screenshots, Diagrams, and Reference diagram are now in Images and diagrams. Tables are now in Tables. Links are now in Links. Introductions import { PublicStats } from "~/components"; The introductory parts of a page sit at the top and tell a reader what the page covers, who it is for, and whether to keep reading. This page covers three: context, introduction, and intended audience. Context An introductory paragraph immediately following the page title that explains what a reader can expect from the content, whether steps, concepts, FAQs, or reference materials. Used in: How to, Configuration, FAQ, Concept, Reference, Tutorial Structure varies by content type: How to: an introductory paragraph on the steps and what they accomplish. Provide context that is not in the section heading. End with a colon if it immediately precedes the steps, or a period if there is more material such as a note between the context and the procedure. Do not use a partial sentence that the numbered steps complete. Configuration: a paragraph right after the title that introduces the feature, contextualizes the configurations the reader will encounter, and links to other relevant documentation. FAQ: an introductory paragraph on the section and what a reader can expect from it. Concept: a brief description of why a reader should care about this information. Reference: an introductory paragraph on how and why a reader might use the information on the page. Tutorial: an introductory paragraph on the reader's goal and how they will accomplish it in the tutorial. Consider including the intended audience. Introduction An overview of what the content will cover, used in lengthier documents to help a reader understand whether to invest time in reading it. Used in: Reference architecture, Design guide No longer than half a page, usually one to three paragraphs. The first paragraph should quickly and clearly explain the topic, and the last paragraph should explain what the document contains. For example: Cloudflare One is a secure access service edge (SASE) platform that protects enterprise applications, users, devices, and networks. By progressively adopting Cloudflare One, organizations can move away from their patchwork of hardware appliances and other point solutions and instead consolidate security and networking capabilities on one unified control plane. Such network and security transformation helps address key challenges modern businesses face, including: Securing access for any user to any resource with Zero Trust practices Defending against cyber threats, including multi-channel phishing and ransomware attacks Protecting data in order to comply with regulations and prevent leaks Simplifying connectivity across offices, data centers, and cloud environments Cloudflare One is built on Cloudflare's connectivity cloud, a unified, intelligent platform of programmable cloud-native services that enable any-to-any connectivity between all networks (enterprise and Internet), cloud environments, applications, and users. It is one of the largest global networks, with data centers spanning hundreds of cities worldwide and interconnection with . This document describes a reference architecture for organizations working towards a SASE architecture, and shows how Cloudflare One enables such security and networking transformation. Intended audience A summary of who the content is aimed at and what a reader will learn. Combined with the context or introduction, it gives a reader an understanding of what the page is about and whether the content is relevant for their role. Used in: Reference architecture, Design guide Begin with the subtitle Who is this for? and keep it to one to three paragraphs. The first paragraph should describe the type of person this document was written for. If the document relies on existing knowledge, link to three to five resources the reader can consume first. The final paragraph should contain two to three specific bullets on what the reader will learn. For example: Who is this for? This reference architecture is designed for IT or security professionals with some responsibility over or familiarity with their organization's existing infrastructure. It is useful to have some experience with technologies important to securing hybrid work, including identity providers (IdPs), user directories, single sign on (SSO), endpoint security or management, firewalls, routers, and point solutions. To build a stronger baseline understanding of Cloudflare, we recommend the following resources: What is Cloudflare? | Website (5 minute read) or video (2 minutes) Solution Brief: Cloudflare One (3 minute read) Whitepaper: Reference Architecture for Internet-Native Transformation (10 minute read) Blog: Zero Trust, SASE, and SSE: foundational concepts for your next-generation network (14 minute read) Those who read this reference architecture will learn: How Cloudflare One protects an organization's employees, devices, applications, data, and networks How Cloudflare One fits into existing infrastructure, and how to approach migration to a SASE architecture How to plan for deploying Cloudflare One Last updated A date displayed at the bottom of each page that shows when the content on the page was last modified. This date is pulled from the page's Git history and does not account for modifications to embedded content such as partials. The Last Updated date will be refreshed for any change to a page's content, while the Reviewed property indicates when the page was last explicitly reviewed from beginning to end. Used in All page types. Structure Mon DD, YYYY Mathematical operations Expressions that show how to make a particular calculation. Used in How to, Reference, Tutorial Structure If an operation occurs inside of a code block, use the formatting associated with that programming language. If an operation occurs in text, either leave the equation in plain text with spaces between operators for readability or use math typesetting. Example Correct Incorrect 25 / 30 25/30 𝑒(𝑎𝑃,𝑏𝑄)=𝑒(𝑃,𝑄)𝑎𝑏 e(aP,bQ)=e(P,Q)ab Next steps The end result of a procedure and the actionable steps to take after completing it. When to use it Use next steps in how-to and tutorial pages, at the end of the page. Structure Write one to two sentences that answer: What happens now? What was the end result of the procedure? What should the reader do next? Example You now have a Worker deployed to your account. Next, add a custom domain so visitors can reach it, or explore Workers KV to store data at the edge. Related Next steps should link to related pages based on the content type of the current page. For example, a how-to page should link to relevant troubleshooting or configuration pages, and a get-started page should link to next-level how-to pages. For the full set of required cross-linking patterns by content type, and for link mechanics, refer to Cross-linking requirements. Notes/tips/warnings A colored info box or aside with content (text, images, lists, code blocks) that adds relevant notes that do not fit the text or warns users of specific behavior that can break functionality or impact security. Used in How to, Configuration, FAQ, Concept, Reference, Tutorial Structure Type: note or warning (defines the background color) Aside content (optional) Title/Header Templates To learn how to format notes, refer to Notes and other notation types. Rendered examples :::note[Header text] This is a note with a header. ::: :::note This is a note without a header. ::: :::caution This is a warning. ::: :::tip This is a tip. ::: When should I use a note/warning? Use a note to alert a reader to additional useful information that you cannot integrate into the text. Use a warning to alert a reader to behavior that could impact the security of a users network or break functionality. Recommendations An aside should not contain too much content, since it breaks the normal text flow. For example, up to 3 paragraphs or bulleted lists up to 3 items. If you need to include more content, consider creating a documentation section "Important notes" or similar. Use asides sparingly. Each section should not have more than one aside of the same type. The only exception is a possible availability disclaimer right after the heading. Asides inside task step instructions should not have a header. They take too much space and the background color is enough to distinguish the aside content from regular text. Use a note aside to state the restricted availability of a feature (for example, "Only available for customers on an Enterprise plan.") at the beginning of a page, without a header. Prerequisites Tasks that must be completed or conditions that must be met before a user can complete the steps on a page. When to use it Use prerequisites in how-to and tutorial pages, before the first step. Structure Write prerequisites as a bulleted list. If there is only one prerequisite task or condition, summarize it in a single sentence instead of a list. Example Before you begin, make sure that you have: - A Cloudflare account with your domain added. - An API token scoped to that domain. - Node.js 18 or later installed locally. Related For how to format the list itself, refer to Lists. Product descriptions Statements about the product and its benefits for customers. When to use it Use product descriptions in the Overview (or Landing page), the Support home page, and the Cloudflare Docs home page. Structure There are two product descriptions, short and long. Both appear in the Overview (or Landing page) as part of the introduction to the product. Short description A short summary statement about the product. This does not need to be, and ideally should not be, a complete sentence. Long description A summary of the product and the value or benefits it brings customers. It makes two main assertions: what the product does, and how that benefits the customer. Intent: show what a customer could use the product for. It should not sell like marketing content, but you can draw on marketing statements for good summaries and adjust the tone to be product appropriate. Length: two to four sentences, kept readable at around a 7th grade reading level. Example Short description: Cloudflare Registrar: Cloudflare's domain registrar Long description: Manage your domain with Cloudflare Registrar and add an additional layer of security to your DNS records for free. Steps/tasks/procedures Action-oriented processes that outline steps to take and the order the steps should be taken. Used in How to, Tutorial Structure Single-step procedures: When a procedure consists of just one step, add the step into the introductory sentence. Sub-steps in numbered procedures: In a numbered procedure, sub-steps should be lowercase letters, and sub-sub-steps get lowercase Roman numerals. When a step has sub-steps, treat the step like an introductory sentence. Put a colon or a period at the end of the step where appropriate. Multi-action procedures: Use one step per action. However, you can combine small actions into one step. Multiple procedures for the same task: If there is more than one way to complete a task, pick one procedure to document that is accessible for all users. If all of the procedures need to be documented, use separate headings or pages or tabs to separate the procedures to make it clear to the reader that this is an alternative way to complete the same task. The following guidelines can help you choose which procedure to document: Choose a procedure that lets readers do all the steps using only a keyboard. Choose the shortest procedure. Choose a procedure that uses a programming language that the majority of your audience is familiar with. Repetitive procedures: Use concise procedures to avoid repetitiveness and overwhelming the user with a lot of bold UI elements. Bullets vs. Numbered Lists Post requisites: Not used at this time. If you feel like you need a post requisites section, consider adding the task as the final step of a procedure or moving the content into Next steps. Guidelines for writing procedures If the user must log in to the dashboard as a first step, consolidate logging in and navigation into the first step. Also, write "log in to" (three words) instead of "log into". If the user must press Enter after a step, then include that instruction as part of the step. If the user has to turn a setting on or off, use "turn on/off" — or "turn on/off " for features with long names — instead of "enable/disable". State the purpose of the action before stating the action. Write in the order that the reader needs to follow. State the location of the action before stating the action. If there are multiple headings associated with a set of procedures, restate the location of the action in the first step of each procedure, even if the location is the same as in the previous procedure. Do not use "please." Additional information Use complete sentences. Use parallel structure. Use second person imperative. Refer to the Style Guide for guidance on when to use certain verbs (click, select, choose, etc). For an optional step, type (Optional) as the first word of the step. For example: (Optional) Type an arbitrary string, to be delivered to the target address with each notification delivered over this channel. Do not include keyboard shortcuts. Do not use directional language to orient the reader, such as above, below, or right-hand side. This type of language does not work well for accessibility or for localization. If a UI element is hard to find, provide a screenshot. Use sentences like "The displays." wisely. :::note Usually, you only need this kind of helper sentence if the user ended up in an unexpected location, or if there was more than one possible target location, depending on the options that the user selected. As an alternative, consider adding the mention at the beginning of the next step: "5. In , select Save." ::: Titles The first line of text on a page. H1. Used in All content types Overview, How to, Configuration, FAQ, Changelog, Concept, Reference, Tutorial, Navigation Structure Structure varies by content type. Visit a content type page to see its corresponding title guidelines. In all cases, do not use gerund phrases. Emojis Do not use emojis in page titles or sidebar labels. Emojis can cause issues with search indexing, accessibility tools, and consistent rendering across platforms. Do Do not title: Migrating from Version 2 title: ⬆️ Migrating from Version 2 title: WebSockets title: "✉️ WebSockets" Subtitles Definition The first line of text on a page. H2, H3, etc. Used in All content types Overview, How to, Configuration, FAQ, Changelog, Concept, Reference, Tutorial, Navigation Structure Subtitles are verb or noun phrase that describes the sub-pages in the section. If using verb, do not use the gerund. Write "Install Wrangler", not "Installing Wrangler". Subtitles should never be a question ("How do I install Wrangler?") or a call to action ("Reach out to us if you have a problem"). 3rd-party integration guide A third-party integration guide explains how to use a third-party product with Cloudflare. Because Cloudflare does not control the third party's interface, these guides carry real maintenance risk, so they favor linking to externally maintained documentation over reproducing another product's steps. The tone is instructional and straightforward. When to use it Write a third-party integration guide when a reader needs to connect one specific external product with Cloudflare, and the integration is worth publishing with an ongoing maintenance commitment. It is not: A how-to. A how-to documents a task entirely within Cloudflare, whereas an integration guide crosses into a third-party product Cloudflare does not control. A blog post. Publish an integration guide only with the expectation of maintenance. If you do not intend to maintain it, write a blog post instead. For the full comparison, refer to Content types. Title & description Title: a short verb phrase in the second-person imperative that includes the third-party product name, not a gerund. If the integration is with a Cloudflare technology partner, add the partner component after the title. Description: name the third-party product and the Cloudflare product, state what the integration accomplishes, and note the key prerequisites. Scaffold this page Copy this skeleton and adapt it to your integration: --- title: description: Connect with to . pcx_content_type: integration-guide sidebar: order: 10 products: - product-a --- Introduce what the integration accomplishes and any considerations unique to the third party. ## Prerequisites List what the reader needs on the third-party side before starting. ## Set up the integration Give the steps that complete the integration, linking to the third party's own documentation rather than reproducing its process. ## Related links Point to the third party's maintained documentation and the related Cloudflare product docs. Component guidance Context introduces what the steps accomplish and any considerations unique to the third party. Prerequisites list what the reader needs on the third-party side before starting. Steps complete the integration, linking out for basic concepts rather than teaching them. Links point to the third party's own documentation, preferred over reproducing its process, and only to reputable sources. What does not fit: step-by-step instructions of the third-party product, which are discouraged because they go out of date the moment the third party changes. Screenshots of the third-party product are the most fragile of all, so avoid them and link to the externally maintained source instead. Frontmatter pcx_content_type: integration-guide products: - product-a - product-b For more details, refer to pcx_content_type. Maintenance and scope Publish a third-party integration guide as post-sales, use-phase content, with the expectation that someone will maintain it. External guides cost more to maintain because Cloudflare does not control the third party's interface and does not get the same visibility into changes. If you want to publish something without that maintenance commitment, write a blog post instead. This content appears most often around Workers, Zero Trust, and Analytics integrations. Examples Integration handled in the Cloudflare dashboard: Enable Logpush to Sumo Logic Device Posture - Carbon Black Linking out to external documentation: GitHub SMS notifications using Twilio Instructions in both the third-party environment and the Cloudflare dashboard, which is discouraged but sometimes acceptable: IdP integration - Microsoft Entra ID Managed deployment - Partners - Jamf Writing for AI and agents Link, do not reproduce. Point to the third party's own documentation for its steps, because reproduced instructions and screenshots go stale as soon as the external product changes. Complete prerequisites. State exactly what the reader needs on the third-party side before starting, because an agent cannot complete an integration it is not set up to reach. Name both products. Name the third-party product and the Cloudflare product in the title and context, so a reader or agent can match the guide to the integration they need. Changelog import { Render, Type, MetaInfo } from "~/components"; A changelog logs notable, dated changes to a product. The tone is instructional and straightforward. This page covers how to write one. For the published updates themselves, refer to Changelog. When to use it Write a changelog when you need to record notable, dated changes to a product as an ongoing feed. It is not: A blog post. A changelog entry is a short, factual record of one change, whereas a blog post explains and promotes at length. The documentation of a change. An entry records that something changed and links out, whereas the how-to, reference, or concept is where the change is actually documented. For the full comparison, refer to Content types. Title & description Title: the page title is Changelog. Description: name the product and what the changelog tracks, such as recent changes, new features, and bug fixes. Scaffold this page Component guidance ProductChangelog renders a product's entries on the changelog page, pulling from the entries folder so the page stays current as entries are added. Entries are the body: each dated MDX file in the changelog collection is one notable change, with its own title, description, and date. What does not fit: long-form explanation or promotion. Keep an entry short and factual, and link to the how-to or concept that covers the change in depth. Frontmatter pcx_content_type: changelog products: - product-a - product-b For more details, refer to pcx_content_type. Ownership Product managers and engineers maintain changelogs manually or through an automated process that their team owns. PCX provides a review but does not own creating or writing changelogs. Building a changelog A changelog needs an MDX page file and a corresponding folder of changelog entries. The combination of these files allows us to: Render traditional changelog content on an HTML page. Programmatically create an RSS feed with the changelog content. Pull all our changelog content into a Cloudflare-wide changelog. Changelog page The MDX page needs several special values to pull in the changelog information, highlighted in the sample page. For more information about the ProductChangelog component, refer to ProductChangelog. --- pcx_content_type: changelog products: - dns title: Changelog description: Track recent changes, new features, and bug fixes for Cloudflare DNS. --- import { ProductChangelog } from "~/components"; {/* */} Changelog entries Changelog entries live in a different location of our docs, /src/content/changelog/. Each entry is its own MDX file, similar to the following. --- title: Account-level DNS analytics now available via GraphQL Analytics API description: Authoritative DNS analytics can now be accessed on the account level via the GraphQL Analytics API. products: - dns date: 2025-06-19 --- Authoritative DNS analytics are now available on the **account level** via the [Cloudflare GraphQL Analytics API](/analytics/graphql-api/). This allows users to query DNS analytics across multiple zones in their account, by using the `accounts` filter. Here is an example to retrieve all DNS queries across all zones in an account that resulted in an `NXDOMAIN` response over a given time frame. Please replace `a30f822fcd7c401984bf85d8f2a5111c` with your actual account ID. ```graphql graphql-api-explorer title="GraphQL example for account-level DNS analytics" query Viewer { viewer { accounts(filter: { accountTag: "a30f822fcd7c401984bf85d8f2a5111c" }) { dnsAnalyticsAdaptive( limit: 10 filter: { date_geq: "2025-06-16" responseCode: "NXDOMAIN" date_leq: "2025-06-18" } orderBy: [datetime_DESC] ) { zoneTag queryName responseCode queryType datetime } } } } ``` To learn more and get started, refer to the [DNS Analytics documentation](/dns/additional-options/analytics/#analytics). Entry properties Each changelog entry has the following properties: title Shown in the title heading and on social media embeds. description Shown in social media embeds. date This should be a date in YYYY-MM-DD format. For example, 2025-02-04. products The products list is case-sensitive. Only use lowercase. This should be an array of strings, each referring to the name of a file in the products collection without the file extension. The folder that your entry is in, such as src/content/changelog/workers/2025-02-13-new-product-feature.mdx, is inferred as part of this property. If you do not want to associate the entry with additional products, you can omit it from the frontmatter entirely. If you wish to reference a product that does not exist in this collection, such as one that resides in the subpath of an existing product, you can create a "metadata only" entry: name: Workers Observability product: title: Workers Observability url: /workers/observability/ group: Developer platform show: false hidden If true, this page will be accessible from the direct link, but hidden from the main changelog page and all RSS feeds. If true, will also add a noindex property so the page is not indexed by search crawlers. Writing for AI and agents Dated, atomic entries. Give each change its own dated entry with a title and description, because an agent extracts and orders changes by entry rather than by scanning prose. Literal dates and products. Use YYYY-MM-DD dates and exact product names in frontmatter, so a reader or agent can filter and sort the feed reliably. Link out for depth. Keep the entry to the change itself and link to the how-to or concept that explains it, because the changelog records what changed, not how to use it. Concept import { Render } from "~/components"; A concept page builds the reader's mental model of a topic: what a thing is, why it works the way it does, and where its boundaries lie. It serves anyone getting oriented or already operating the product and filling in the why. The tone is instructional, descriptive, approachable, and supportive. When to use it Write a concept page when readers keep needing the same explanation in the middle of other pages, because that recurring detour is the signal the model deserves its own home. It is not: A how-to. A concept carries no procedural steps or configuration walkthroughs. Code that shows the idea is welcome, code the reader follows along with is not. A reference. Reference is complete and neutral, whereas a concept is selective and opinionated, so "we recommend" belongs here. An overview. An overview routes the reader onward, whereas a concept explains. Keep one concept per page. For the full comparison, refer to Content types. Title & description Title: a concise noun phrase naming the concept. Use "About" for a high-level product concept page. Otherwise use a feature name, functionality, or Internet concept such as Health checks or CDN. Do not use "Overview", "Introduction", or "How it works", because they name the genre rather than the subject. As a self-check, a good title still reads naturally with "About" in front of it. Description: state what the concept is and what it means for the reader's code or choices. Scaffold this page Component guidance Prose is the primary component. Short paragraphs, one idea per section: this is the type where writing quality carries the page. Diagrams and illustrative code fit when they show the model, and a diagram always ships with a text equivalent. Comparison tables fit where there is a genuine either/or, alongside the boundaries the concept is confused with. What does not fit: Steps (a concept has no procedural steps or walkthroughs), Tabs (a concept does not vary by platform, and if it does it is two concepts), and Cards. Frontmatter pcx_content_type: concept products: - product-a - product-b For more details, refer to pcx_content_type. Writing for AI and agents Self-contained definition. Lead with the contract in checkable terms such as "at least once" or "not ordered" rather than reassuring adjectives, because the definition paragraphs are what an agent retrieves and quotes, so they must stand on their own. Literal payloads. Keep illustrative code and payloads in fenced blocks with complete, realistic values rather than paraphrase. Declarative boundaries. Write the boundaries as flat declarative bullets stating what the concept is not, so an agent can lift them without reconstructing the prose. Configuration A configuration page shows the specific settings, values, and options for a configuration-intensive feature, so a reader can copy the right setup for their use case rather than follow a procedure. Also known as use cases, configurations are reference pages, not instructions. The tone is plain, descriptive, and straightforward. When to use it Write a configuration when a feature is configuration-intensive, such as rules, and readers mainly need to know which settings and values produce a given outcome. It is not: A how-to. A how-to walks through the steps to complete a task, whereas a configuration only shows the settings and values for a setup, with no procedural steps. A tutorial. A tutorial teaches through a guided project, whereas a configuration is a reference the reader consults for the right values, not a lesson. A reference. A reference exhaustively documents every parameter, whereas a configuration curates example setups for common use cases. For the full comparison, refer to Content types. Title & description Title: noun-based, naming the feature being configured, because a configuration describes ways to set up a feature rather than guiding the reader toward a goal. Description: name the product or feature configured, the use case it serves, and the key settings or values covered. Scaffold this page Copy this skeleton and adapt it to your feature: --- title: configuration description: Configure for , covering . pcx_content_type: configuration sidebar: order: 10 products: - product-a --- Introduce the feature in two or three sentences, frame which configurations the reader will encounter, and link to related documentation. ## State the outcome this configuration produces, then give the settings and values in a table. | Setting | Value | Notes | | -------------- | -------------------------- | ---------------- | | | | | Component guidance Tables are the signature: a reference table with a 1:1 correspondence between each setting the reader can change and the value to enter or select for a given use case. Navigation helps readers find the right configuration when a feature has many. What does not fit: step-by-step procedures. If you find yourself writing instructions, use a how-to, tutorial, or example instead. Frontmatter pcx_content_type: configuration products: - product-a - product-b For more details, refer to pcx_content_type. Organizing configurations Open each configuration with a short context paragraph after the title that introduces the feature, frames which configurations the reader will encounter, and links to related documentation. Group the body by feature, giving each feature its own settings table so the reader can scan to the setup that matches their use case. Writing for AI and agents Complete setting-value pairs. Give every table row an explicit setting and the exact value to enter or select, because an agent applies the pair directly with no room to infer. Use-case framing. State the outcome each configuration produces in its context, so a reader or agent can match a goal to the right table without reading a procedure. Instructions point outward. Link to the how-to, tutorial, or example that carries any steps, because a configuration itself is not executable as a procedure. Design guide A design guide helps a reader plan and design a specific solution with Cloudflare, focusing on the architecture decisions behind that solution before any configuration. A design guide is a focused subset of a reference architecture. The tone is instructional and straightforward. When to use it Write a design guide when a reader needs to plan the architecture of one specific solution, understanding the decisions and trade-offs before they build it. It is not: A reference architecture. A reference architecture describes a broad, product-spanning architecture, whereas a design guide narrows to planning one specific solution within it. A how-to. A how-to gives the steps to configure a product, whereas a design guide reasons through the architecture decisions and trade-offs before any configuration begins. For the full comparison, refer to Content types. Title & description Title: a short verb phrase in the second-person imperative, not a gerund. Prefer "Securely deliver applications with Cloudflare" over "Securely delivering applications". Description: name the solution the reader will plan and design, the Cloudflare products involved, and the architecture decisions covered. Scaffold this page Copy this skeleton and adapt it to your solution: --- title: description: Plan and design with , covering . pcx_content_type: design-guide sidebar: order: 10 products: - product-a --- Open with two or three paragraphs describing the subject matter and the end state of the solution. ## Intended audience Summarize who the guide is for and what they will learn. ## Describe the design and the decisions and trade-offs behind it, include a diagram of the architecture, and link out to the how-tos and tutorials that implement it. ## Related links Point to the reference architecture and product documentation the design draws on. Component guidance Introduction opens with two to three paragraphs describing the subject matter and the end state of the solution the guide details. Intended audience summarizes who the guide is for and what they will learn. Diagrams show the architecture, which is central to a design guide. Notes and warnings flag caveats and trade-offs that affect how the design applies. Related links point to the reference architecture and product documentation the design draws on. What does not fit: step-by-step configuration procedures. A design guide plans the solution, so link out to the how-tos and tutorials that implement it. Frontmatter pcx_content_type: design-guide products: - product-a - product-b For more details, refer to pcx_content_type. Examples Securely deliver applications with Cloudflare Writing for AI and agents Design, not steps. Describe the architecture and the decisions behind it, linking out to the how-tos and tutorials that implement them, because a design guide is a plan an agent reasons from, not a procedure it runs. State the end state. Describe the finished solution the guide produces up front, so a reader or agent knows the target before following the design. Name the audience and assumptions. State who the guide is for and the infrastructure it assumes, because a design guide is only actionable for a reader with the right context. FAQ An FAQ page collects common questions on a topic with short, direct answers, giving a reader a fast path to a single fact and improving the discoverability of the product. The tone is straightforward, educational, and authoritative. When to use it Write an FAQ only when a page is genuinely a list of questions with direct answers. If the list grows beyond roughly 10 questions, revisit whether some answers belong elsewhere in the documentation. It is not: A how-to or tutorial. Procedural questions belong in a how-to or tutorial, whereas an FAQ calls out only a few common ones and links back to them. A glossary. Definition questions belong in the glossary, whereas an FAQ repeats only the essential, recurring definitions and links out. A troubleshooting page. A troubleshooting page catalogs errors and their fixes, whereas an FAQ surfaces only the most common issues as questions. For the full comparison, refer to Content types. Title & description Title: the page title is FAQ. In a large multi-section FAQ, each child page takes the name of its section instead. Description: name the product and the key topic areas the questions cover. Scaffold this page Copy this skeleton and adapt it to your topic: --- title: FAQ description: Answers to common questions about , covering . pcx_content_type: faq sidebar: order: 10 products: - product-a --- Open with a short paragraph on the topic and what the reader can expect to find. ## Lead with the direct answer, add one or two sentences of context, and link to the how-to, tutorial, or glossary that answers it in full. ## Answer completely and link out to the source of truth. Component guidance Context opens the page with a short paragraph on the topic and what the reader can expect to find. Navigation lists the sections once an FAQ is large enough to need them, so a reader can jump to the right group. Links carry the reader from a called-out question to the how-to, tutorial, or glossary entry that answers it in full. What does not fit: long procedures or exhaustive definitions. Keep those in their canonical how-to, tutorial, or glossary and link to them. Frontmatter pcx_content_type: faq products: - product-a - product-b For more details, refer to pcx_content_type. Writing questions and answers Write each question in full and from the reader's point of view, using the first person. Prefer "Can I use wildcards when creating policies?" over "Can users use wildcards when creating policies?". Answer completely, and when the question is phrased as yes or no, lead with the direct response before adding context. Prefer "Yes. Cloudflare Access supports several providers simultaneously." over an answer that omits the leading "Yes". Question types Most questions fall into one of five types, each with its own answer shape: Type Question shape How to answer Yes/No "Can I...", "Does the product..." Lead with Yes or No, then one or two sentences of context Procedural "How do I...", "How does it work?" Give a concise answer, then link to the how-to or tutorial that covers it Definition "What is...?" Give a short, dictionary-style definition, then link to the glossary Scenario "What if...?" Say whether the product fits in the first sentence, add context, link out Troubleshooting "I see...", "It does not work when..." Give the reason, then short actionable steps, then link to deeper docs Structuring larger FAQs Small pages, up to about 10 questions, need no sections: a title, a context paragraph, then the questions and answers. Medium pages add section headings and a navigation menu that lists them. Large FAQs, for product suites such as Cloudflare One, split each section onto its own child page: the main page lists the sections with a one-line context and a button to each child page, and each child page carries its section's questions under breadcrumbs back to the landing page. Writing for AI and agents Full question text. Write each question with its complete text from the reader's point of view, because an agent matches on the whole question, not a truncated heading. Direct answers. Lead with the direct response, Yes or No where the question is yes/no, so a reader or agent gets the fact in the first sentence. Link to the source of truth. Point every procedural, definition, or scenario answer to its canonical how-to, tutorial, or glossary entry, because the FAQ is a shortcut, not the authority. Get started import { Render } from "~/components"; A get-started page takes a new user from not using a product to a first working setup by the shortest honest path. The tone is instructional and encouraging. When to use it Write a get-started page when a new user needs the shortest path from nothing to one working result, before they explore the product in depth. It is not: A how-to. A how-to completes one specific task for a reader who already uses the product, whereas a get-started page delivers a new user's first success end to end. A tutorial. A tutorial teaches through a longer guided project, whereas a get-started page stops at the first working result and routes the reader onward. For the full comparison, refer to Content types. Title & description Title: the page title is Get started. Description: name the product, summarize the first setup the reader completes, and note the key prerequisites. Scaffold this page Component guidance Prerequisites list what the reader needs before starting, such as an active zone, a subscription or plan, or setup outside Cloudflare. Steps lead the reader to product adoption, covering the minimum setup plus the most general use case, and often reuse partials from the how-to pages. Links close the page with next steps that point the reader toward deeper configuration once they have a working setup. What does not fit: exhaustive configuration or edge cases. Keep those in how-tos and reference pages, and link to them. Frontmatter pcx_content_type: get-started products: - product-a - product-b For more details, refer to pcx_content_type. Examples Waiting Room: Get started Writing for AI and agents Shortest honest path. Include only the steps that reach a first working result, because a get-started page is judged by how quickly a reader or agent reaches success, not by coverage. Show the result. State and show the working outcome the steps produce, so a reader or agent can verify success before moving on. Complete prerequisites. State exactly what the reader needs before starting, because an agent cannot begin a setup it is not equipped to reach. How to import { Render } from "~/components"; A how-to explains how to complete a single task within a product. The tone is instructional and straightforward. When to use it Use a how-to when the reader has already chosen a product and needs to complete one specific task within it. It is not: A tutorial. A tutorial teaches by building something and cannot fail the reader, whereas a how-to serves someone mid-task who already knows the goal. A concept. If you find yourself explaining why the product works this way for more than a sentence, move it to a concept page and link to it. For the full comparison, refer to Content types. Title & description Title: a short verb phrase in the second-person imperative. Do not use gerunds, bare nouns, or a "How to" prefix. Description: start with a verb, name the Cloudflare product or feature, and state the task it accomplishes, then add a key detail or prerequisite. Scaffold this page Component guidance Steps are the signature structure: the Steps component or a plain ordered list, whichever you use, must read identically in the Markdown twin. If a page has no steps, question whether it is a how-to. Tabs and code groups carry variant axes such as language, platform, or CLI versus dashboard inside one canonical page. For alternative methods, pick the recommended one and link the rest, and never duplicate the page. Callouts warn before a destructive step. A page drowning in exception callouts has the wrong happy path. End in a fixed order: verification, then the irreversible closing step if there is one, then optional blocks, then Next steps. Never end on the last numbered step. Multi-procedure pages number their section headings ( ## 1., ## 2.) so the sequence is unambiguous, and cap each phase at roughly ten steps. Frontmatter pcx_content_type: how-to products: - product-a - product-b - product-c For more details, refer to pcx_content_type. Writing for AI and agents Self-contained steps. Name the product area, the full command, and the exact label the reader selects, and never use a positional reference such as "as configured above." Literal output. Keep expected output in fenced code blocks with complete, realistic values rather than truncated placeholders, because agents match on the literal text you show. Twin-safe steps. When a step's only copy lives inside a tab or other component, make sure it survives as labeled text in the Markdown twin so conversion cannot drop it. Content types Every documentation page has a content type: a defined shape for what it contains, how it is structured, and how it is maintained. Choosing the right one keeps pages predictable for readers and agents. Every new product needs an overview and a get-started page, and the other types depend on what a reader needs. This page groups the types by the job they do, so you can tell apart the ones that are easy to confuse. For full guidance on any type, refer to its page in the tables. Task and setup content Types where the reader is getting something done. Content type Choose it when How to The reader has already chosen a product and needs to complete one specific task within it. Tutorial The reader learns by building a real project end to end, where the journey teaches as much as the result. Get started A new user needs the shortest path from nothing to a first working result. 3rd-party integration guide The reader connects one specific external product with Cloudflare, and you commit to maintaining the guide. Configuration A feature is configuration-intensive and the reader mainly needs the settings and values rather than steps. Explanatory and lookup content Types where the reader is trying to understand or find something. Content type Choose it when Concept The reader needs to understand what something is and why it works the way it does. Reference The reader needs to look up complete, neutral details such as every parameter, value, or option. Overview A new reader needs orienting to a product area in a paragraph before being routed onward. FAQ Common questions each deserve a short, direct answer with a link to the source of truth. Troubleshooting The reader has hit a specific error or symptom and needs the cause and the fix. Architecture and planning content Types that design a solution rather than implement it. Content type Choose it when Reference architecture You show, at the design level, how several products fit a customer's environment across use cases. Design guide The reader plans one specific solution and the architecture decisions behind it before building. Signpost and record content Types that route the reader onward or log what changed. Content type Choose it when Navigation An area has enough child pages that a reader needs a signposted entry point into them. Changelog You log notable, dated changes to a product. Navigation A navigation page is a sub-landing page that points a reader deeper into a specific area of the documentation. It carries almost no prose of its own: a short introduction and an automatically generated listing of the child pages under it. The tone is brief and functional. When to use it Write a navigation page when an area of the documentation has enough child pages that a reader needs a signposted entry point into them. It is not: An overview. An overview introduces a product and orients a new reader with prose, whereas a navigation page mainly signposts the child pages under it. A concept. A concept explains how something works, whereas a navigation page explains nothing and only routes the reader onward. For the full comparison, refer to Content types. Title & description Title: name the section or area the page fronts, matching the heading a reader clicked to arrive. Description: invite the reader to explore the area, and name the key topics the child pages cover. Scaffold this page Copy this skeleton and adapt it to your area: --- title:
description: Explore , covering . pcx_content_type: navigation sidebar: order: 10 products: - product-a --- import { DirectoryListing } from "~/components"; Introduce the area in one or two sentences, then let the listing route the reader to the child pages. Component guidance DirectoryListing carries the body of the page: it displays the child pages of a folder as a list of links, generated automatically so the listing stays current as pages are added or removed. What does not fit: substantive explanation or procedures. A navigation page holds no content of its own, so put explanations on the pages it links to. Frontmatter pcx_content_type: navigation products: - product-a - product-b For more details, refer to pcx_content_type. Examples Logs: Enable destinations Cloudflare Tunnel: Get started Writing for AI and agents Automatic listing. Use DirectoryListing rather than a hand-written list, so the routes an agent follows are always the current child pages. No orphaned content. Keep explanations and procedures off the navigation page, because an agent that lands here should be routed onward, not asked to read. Descriptive child titles. The listing shows each child page's title, so write those titles to stand alone, because they are the only signal a reader or agent has when choosing where to go. Overview import { Render } from "~/components"; An overview is the landing page a reader reaches first in a product area: it answers "what is this, and where do I start?" in one paragraph, then routes onward. The tone is accessible, welcoming, conversational, and outspoken. When to use it Use an overview as the single landing page for a product or major product area, the page its sidebar section opens on. It is not: A concept page. Move architecture and tradeoffs to a concept page and link to them. An overview orients rather than explains. A bare table of contents. A list of links with no orientation only duplicates the sidebar. A marketing page. The reader has already clicked into the docs. For the full comparison, refer to Content types. For a live example, refer to the Argo Smart Routing overview. Title & description Title: the name of the product, product group, or content area, as a noun. Do not append "documentation", use a gerund phrase, or use "Introduction". Description: name the Cloudflare product and what it does for whom in one sentence, then state the plans it is available on. Scaffold this page Component guidance Cards are the signature components: this is the one type where cards are the body content, because routing is the body. Keep card text to a name plus one line, because a card that explains is a concept paragraph in a box. In the Markdown twin cards flatten to link-plus-description lists, so write the one-liners so they work in both forms. Link lists beat cards when the grid forces padded copy, or when a group genuinely must run past the roughly five-link cap, because prose lists scan better at volume. What does not fit: Steps (nothing is performed here), code blocks (nothing is looked up, though inline code in the orientation line is fine), and accordions (an overview with hidden content is hiding its own map). Frontmatter pcx_content_type: overview products: - product-a - product-b - product-c For more details, refer to pcx_content_type. Managing overview pages Every product or major product area must have an overview, so the answer to a weak one is always to strengthen it, never to remove it. If a page reads like a bare table of contents, add the orientation that says what the area is and where to start. Do not delete it and let the sidebar stand in. The only page you hide is a structural group node: a folder that exists purely to group its children in the sidebar and was never a content page. You cannot delete a folder's index.mdx without a build error, so hide the placeholder and redirect readers past it by setting group.hideIndex to true: --- title: Placeholder sidebar: group: hideIndex: true --- Writing for AI and agents Self-contained orientation. Write the opening paragraph so it stays accurate in isolation, because it is what an agent quotes when asked what the product is. Do not lean on the title or a later section to complete its meaning. Literal availability. State availability with literal plan, region, or release-stage names rather than a paraphrase. Load-bearing links. Use real, current routes, because a stale route here strands a reader at the front door. Reference architecture A reference architecture is a high-level design document that shows how Cloudflare products fit into a customer's existing infrastructure and maps their use cases to Cloudflare solutions. The tone is guiding and straightforward. This page covers how to write one. For the published architectures themselves, refer to Reference architectures. When to use it Write a reference architecture when you need to show, at the design level, how several Cloudflare products combine to fit a customer's environment and use cases. These documents are typically detailed. It is not: A concept. A concept explains one idea in depth, whereas a reference architecture shows how multiple products fit together in a real environment. A how-to. A reference architecture describes and designs rather than giving procedural steps. For a single architecture that needs little written explanation, use a reference architecture diagram instead. For the full comparison, refer to Content types. For live examples, refer to Cloudflare Load Balancing Reference Architecture, Magic Transit Reference Architecture, and Evolving to a SASE architecture with Cloudflare. Title & description Title: a noun phrase naming the architecture or solution, such as "Cloudflare Load Balancing Reference Architecture". Description: name the solution and the products, say how they fit into existing infrastructure and for which use case, and name the intended audience, such as IT and security professionals. Scaffold this page Copy this skeleton and adapt it to your architecture: --- title: description: How fit for , written for . pcx_content_type: reference-architecture sidebar: order: 10 products: - product-a --- Open with two or three paragraphs on the subject matter, then state who the document is for and what they will learn. ## Present the reference diagram with numbered callouts, and explain each element in prose so the meaning survives without the image. ## Map the customer use case to the Cloudflare solution, and flag any caveats that affect how the architecture applies. ## Related links Link the supporting how-tos, concepts, and product documentation with current routes. Component guidance Diagrams are the signature component: a single reference diagram reflects the overall architecture, with captions and numbered callouts explaining each element, and supporting diagrams develop specific parts. Introduction and intended audience open the document in prose, with two or three paragraphs on the subject matter followed by who it is for and what they will learn. Notes and warnings flag caveats that affect how the architecture applies. PublicStats surfaces Cloudflare network statistics where they strengthen the case for the architecture. What does not fit: procedural steps, because a reference architecture designs rather than instructs. Link a how-to for implementation. Frontmatter pcx_content_type: reference-architecture products: - product-a - product-b For more details, refer to pcx_content_type. Reference architecture diagrams A reference architecture diagram is the lighter variant: a single diagram with numbered callouts and just enough text to explain it, for a solution that does not need a full written architecture. The tone is instructional and straightforward. When to use it: reach for it when one diagram carries the solution and needs little written explanation. Choose a full reference architecture when the design needs detailed discussion. Title: a noun phrase, as for a full reference architecture. Structure: a single reference diagram, numbered callouts that explain each element, a short description of what the diagram relates to, and related links to supporting content. Frontmatter: set pcx_content_type to reference-architecture-diagram. Writing for AI and agents Text equivalents for every diagram. Explain each numbered callout in prose and give the diagram a text equivalent, because an agent cannot read the image and the meaning must survive without it. Literal product and use-case names. Name the exact Cloudflare products and the use case in text, not only inside the diagram, so the architecture is retrievable on its own. Load-bearing links. Link the supporting how-tos, concepts, and product docs with real, current routes, because the architecture points outward to implementation. Reference import { Render } from "~/components"; A reference page enumerates the facts about one nameable surface, such as a file format, a command, or a set of limits, completely and in a uniform structure. The tone is plain and straightforward. When to use it Reach for a reference page when a reader needs to look up exact facts about one surface. Two laws govern the type: completeness, because a missing entry breaks a reference the way a missing word breaks a dictionary, and uniformity, because every entry answers the same questions in the same order. It is not: A how-to. Reference describes, never instructs. A "to do this, first ..." entry means you extract a how-to and link it. A concept. Opinion and rationale live on the concept page, so one orienting sentence with a concept link is the whole prose allowance at the top. A dumping ground. "Miscellaneous" is where facts go to become unfindable. Keep one surface per page and mirror the product's own structure. For the full comparison, refer to Content types. For live examples, refer to Common Cf-Polished statuses and Logpush API configuration. Title & description Title: the surface's name as the reader searches for it, such as "CLI commands", "Event types", or "Limits". Use "Reference" for a single standalone page, use nouns for a section with child pages, and add "reference" to a noun only when the bare name is ambiguous, as in "Retry policy reference". Description: name the entry kinds the surface accepts and the fact categories each entry lists. Scaffold this page Component guidance Tables are the signature component: a quick-reference table before the entries makes the common lookup zero-scroll. Keep tables simple, because merged cells and meaning-by-layout break both scanning and extraction. Definition lines carry the same facts in a fixed order, such as type, default, required, and constraints, bolded or badged consistently across every entry. DirectoryListing links the child pages when the reference is a section rather than a single page. What does not fit: Steps, Cards, and callouts (a fact that needs a warning usually belongs in the entry as a constraint), plus tabs or accordions that hide entries (a collapsed entry is invisible to search-and-grab readers and to extraction). Frontmatter pcx_content_type: reference products: - product-a - product-b For more details, refer to pcx_content_type. Completeness and source of truth A reference is complete or clearly scoped, with nothing in between, so if a subset lives elsewhere the first line says where. Give every fact exactly one source: generate values that live in code or a schema, and where generation does not yet exist, name the source so maintainers know what to diff against. Hand-maintained fact pages such as limits or quotas carry a visible reviewed date. When a surface passes roughly 30 entries, split it along its own seams, such as file layout or command groups, never alphabetically. Writing for AI and agents Self-identifying entries. Give every entry heading its full name, such as the dotted path retry.max_attempts rather than max_attempts under a "Retry" heading, so a retrieved chunk carries its own identity. Machine-checkable values. State ranges, defaults, and limits as literal values rather than "a reasonable number", and keep examples minimal in fenced blocks with realistic values. Nothing hidden. Keep every entry in the open, because a collapsed or tabbed entry is invisible to extraction. The Markdown twin of a reference page is the page. Troubleshooting import { Render } from "~/components"; A troubleshooting page pairs each failure a reader hits with its cause and the steps that resolve it, organized by symptom rather than by question. The tone is guiding, straightforward, and solution-oriented. When to use it Troubleshooting lives in two places: inline as a "What if ..." callout or accordion on the page where the failure happens, and on a dedicated troubleshooting page per product area once the inline entries pass roughly five or the same failure spans several pages. Reach for it to help a reader recover from a failure. It is not: A how-to. A how-to pursues a goal, whereas troubleshooting recovers from a failure. An error reference. A complete per-code catalog is reference material. This page covers symptoms, multi-cause problems, and the "it is slow or flaky" cases that error codes do not capture. A global FAQ. A troubleshooting page is organized by failure, not by question. For the full comparison, refer to Content types. Title & description Page title: "Troubleshooting" followed by the product, feature, or area, as in "Troubleshooting delivery". Entry titles: the verbatim symptom, ideally the exact error message, because "Error: signature timestamp outside tolerance" beats "Signature problems" in search and in a sidebar scan. Trim a long message to its distinctive substring of roughly 70 characters with an ASCII "..." marking the cut, and keep the message type such as "Error:". A symptom with no message gets observable phrasing, as in "Deliveries succeed but arrive twice". Description: state that the page fixes the common failures in the area, by symptom. Scaffold this page Component guidance Fenced code blocks carry the verbatim error message, the match target for search, readers, and retrieval. Show one realistic concrete instance with real values, and never paraphrase the message or elide its distinctive part. Bold Cause, Fix, and Verify labels give every entry the same internal order, so a panicking reader can skip straight to the fix. Details accordions fit the inline form at a feature page's end, but on a dedicated page the entries stay open, because a hidden symptom is unfindable. What does not fit: Cards, a marketing tone, and reassurance offered without a fix. Frontmatter pcx_content_type: troubleshooting products: - product-a - product-b For more details, refer to pcx_content_type. Organizing entries Order entries by frequency, most common failure first, and let a data-loss failure jump the queue. Keep troubleshooting inline until a product area passes roughly five entries, then move it to a dedicated page and leave a link behind at the inline site. Every workaround states its cost and names its permanent alternative. A dedicated page ends with a "Still stuck?" section that gives the escalation path and a collect-this-first list, which is the type's honesty clause: a page implying completeness strands the reader with the one failure it missed. Writing for AI and agents Self-contained entries. Write each entry so it stands alone, because entry N is retrieved without the entry before it and without the page intro. Give it the full symptom, cause, and fix. Executable fixes. Structure cause and fix as declaratives an agent can run: "check your configuration" is not a fix, a concrete command such as hookline test-event --endpoint is. Verbatim symptoms. Show the error message verbatim in a fenced block as one concrete instance, so search, readers, and retrieval all match on the literal text. Tutorial import { Render } from "~/components"; A tutorial takes a newcomer from nothing to a working project, one visible result at a time, with the author carrying all of the responsibility. The tone is guiding, straightforward, educational, and authoritative. When to use it Write a tutorial when competence requires assembling several of the product's pieces into one real project, the kind of value that shows only when features work together. It is the most expensive type to build and keep true, so reach for one deliberately. It is not: A quickstart. A quickstart proves the product works in minutes, whereas a tutorial builds competence through a meaningful project in about an hour. A how-to. A how-to serves a competent reader who carries themselves, whereas a tutorial's reader knows nothing, so when something breaks it is the tutorial's fault. A concept course. A tutorial teaches by doing rather than by explaining. Link the concept instead of unfolding it. For the full comparison, refer to Content types. For a live example, refer to Workers tutorials. Title & description Title: a short verb phrase in the second-person imperative, named by the outcome, such as "Build an order-notification service". Do not use "Learn ..." or "Tutorial 1". Description: state what the reader will build and what they will be able to do afterward, then give an honest time estimate. Scaffold this page Component guidance Steps or numbered ## parts are the spine, and every part ends with the verbatim "You should see" output that proves it worked. Never skip one. Error-recovery prose at the points readers actually stumble is happy-path content, not an exception callout, because in a tutorial an anticipated error is not an exception. PackageManagers keeps install commands in sync, and ListTutorials surfaces the tutorial in listings. What does not fit: Tabs and options of any kind (the author already chose the one path, and per-stack means per-page), long conceptual asides (link out instead), and anything that hides steps. Frontmatter pcx_content_type: tutorial difficulty: Beginner products: - product-a - product-b Set difficulty to Beginner, Intermediate, or Advanced, and stamp reviewed with the date you last ran the tutorial end to end. For more details, refer to pcx_content_type. Keeping tutorials current A tutorial is the most expensive type to keep true, because it must work for every reader, every time, on a cold machine, and a broken tutorial convinces a newcomer that the product itself is broken. Fewest and freshest wins, so one tested tutorial beats five stale ones. Pin every version the tutorial depends on, re-run it end to end on a clean environment each release, and stamp reviewed with that date. ListTutorials Writing for AI and agents Self-contained parts. Give every part a full-context heading, the full command, and the verbatim result, so a reader or agent landing mid-tutorial knows where they are, and never use a positional reference such as "as configured above." Literal output. Keep every expected output in a fenced code block with complete, realistic values, because that "You should see" text is what agents and readers match against. Pinned versions. Name and pin every version in the prerequisites, so the tutorial does not silently drift off the latest release. AI consumability import { Tabs, TabItem, Render } from "~/components"; We have various approaches for making our content visible to AI as well as making sure it's easily consumed in a plain-text format. AI discoverability The primary proposal in this space is llms.txt, offering a well-known path for a Markdown list of all your pages. Textual representation of interactive elements HTML is easily parsed - after all, the browser has to parse it to decide how to render the page you're reading now - it tends to not be very portable. This limitation is especially painful in an AI context, because all the extra presentation information consumes additional tokens. For example, given our Tabs, the panels are hidden until the tab itself is clicked: One Content Two Content If we run the resulting HTML from this component through a solution like turndown: - [One](#tab-panel-6) - [Two](#tab-panel-7) One Content Two Content The references to the panels id, usually handled by JavaScript, are visible but non-functional. Turning our components into "Markdownable" HTML To solve this, we use Markdown for Agents, which converts HTML to Markdown at the Cloudflare network layer. It handles: Removing non-content tags ( script, style, link, etc.) Transforming interactive components like Tabs into standard unordered lists Adapting code block HTML into clean Markdown fenced code blocks Taking the Tabs example from the previous section, Markdown for Agents will give us a normal unordered list with the content properly associated with a given list item: - One One Content - Two Two Content You can request any page as Markdown in two ways: Send a request with an Accept: text/markdown header: curl "https://developers.cloudflare.com/docs-for-agents/" \ --header "Accept: text/markdown" Append index.md to the URL — for example, /docs-for-agents/index.md Saving on tokens Most AI pricing is around input & output tokens and Markdown greatly reduces the amount of input tokens required. For example, let's take a look at the amount of tokens required for the Workers Get Started using OpenAI's tokenizer: HTML: 15,229 tokens Markdown: 2,110 tokens (7.22x less than HTML) When providing our content to AI, we can see a real-world ~7x saving in input tokens cost. Curating content Other than the work making our content discoverable, most of the other work of making content for AI aligns with SEO or content best practices, such as: Using semantic HTML Adding headings Reducing inconsistencies in naming or outdated information For more details, refer to Google's AI guidance. noindex directives The only special work we have done is adding a noindex directives to specific types of content (via a frontmatter tag). {/* prettier-ignore */} For example, we have certain pages that discuss deprecated features, such as Wrangler 1. While technically accurate, they are no longer advisable to follow and could potentially confuse AI outputs. At the moment, it's unclear whether all AI crawlers will respect these directives, but it's the only signal we have to exclude something from their indexing (and we do not want to set up WAF rules for individual pages). Image maintenance Though valuable for user understanding, images are difficult to maintain. We have a few strategies that we use to help make this easier. Guidelines We support a few different types of images in our docs, including: Diagrams Screenshots Of these, we prefer Mermaid diagrams because they are searchable and easily changeable. The "cost" of updating a Mermaid diagram is much lower than re-taking a screenshot or working with a designer to update a diagram. Maintenance The best way to improve image maintenance is to avoid using them. The other way to streamline maintenance is to remove images that are no longer referenced in your documentation. This pattern becomes particularly helpful if you need to audit images for UI changes or leaked information, because then you are not wasting time looking at unused images too. We do that through a combination of GitHub actions. Flag unused images We have a specific GitHub action to flag unused images. What the GitHub action does is: Finds all .png or .svg files in our content. Checks to see if those files are referenced in any of our MDX files. Creates a GitHub issue if there are unreferenced files. Evaluate image paths In combination with flagging unused images, we also have logic in our build process to validate image paths. export default defineConfig({ site: "https://developers.cloudflare.com", markdown: { smartypants: false, remarkPlugins: [remarkValidateImages], rehypePlugins: [ rehypeMermaid, rehypeExternalLinks, rehypeHeadingSlugs, rehypeAutolinkHeadings, // @ts-expect-error plugins types are outdated but functional rehypeTitleFigure, rehypeShiftHeadings, ], }, This ensures that the build-time nimbus/image-ref lint rule validates all image paths. If the path does not exist, we throw an error and prevent the site from building. When paired with flagging unused images, this path validation ensures that a tech writer can safely delete unused files in a pull request. So long as the site builds correctly, you have only deleted image files that are not referenced anywhere. How we docs import { DirectoryListing } from "~/components"; This section shares how Cloudflare approaches docs strategically, covering topics like how we built our site and how we think about redirects. The goal is twofold because it: Encourages deep thinking about how we approach things (and if they could be better). Contributes back to the open-source ecosystem. We get a lot of benefits from being open source and we want to give back. We hope you learn from the topics below. As always, submit an issue if you find something inaccurate or unclear. Link maintenance Though links are an important part of documentation, they also have their own maintenance cost. We have a few strategies we use to make link maintenance easier. Link types Documentation uses three types of links: external, internal, and anchor. For each type, we think through a few different aspects of the experience. External: Source of truth: Another site. Why does it break: Another site changed its content. Customer experience of a break: 404 page on another site. Internal: Source of truth: Your site. Why does it break: Your site changed its content. Customer experience of a break: 404 page on your site. Anchor: Source of truth: Your site. Why does it break: Your site changed its content. Customer experience of a break: Page load on your site. Content might be further down the page or have been moved to another page. Checks Internal links Of these three link types, only Internal links: Happen within the context of a change to your site's content. Universally lead to a bad customer experience (a 404 page). Are easily auditable within the current context. For these reasons, we choose to make a build fail based on broken internal links. For our implementation, we rely on Nimbus's nimbus/internal-link lint rule, configured in astro.config.ts. We also make two intentional decisions about this link auditing: Absolute links, not relative: We enforce absolute links ( /style-guide/how-we-docs/metadata/) and fail on relative links ( ../metadata/) to avoid time-consuming maintenance in the future. This decision also helps with find/replace work and any future platform migrations. No redirects: We do not consider redirects when evaluating links. We have the current source of truth, so we should utilize that truth to its fullest (as well as helping us avoid redirect chains and future maintenance). External links Though external links are not good for the customer experience, they also don't change within the context of a change to your site's content. Additionally, external link checking can be time consuming and error prone, which can slow down contributions. We use an external SEO tool to help flag these broken external links for us, addressing them as needed (instead of making a build fail because of them). Anchor links Anchor links do not have as dramatic as consequences of being wrong as internal links. If you have a broken anchor link, a customer will either need to manually scroll to the header or, in some cases, go to another page. Because of these characteristics, we run periodic, background checks to flag broken anchor links, using the htmltest library. Metadata Page-level metadata - content type, associated products, last updated, word count - lets you take a broader, more strategic view of your content. It helps you answer questions like the following: As a writer: Am I missing something obvious in the content strategy? What are some pages I should be updating right now? How does X tutorial compare with all tutorials? Is it getting more traffic than the baseline? As a manager: Are we over or underinvesting in a specific product area? Or a specific content type? How does the traffic to this set of products compare to another? How can I communicate broader trends to my stakeholders? You cannot answer these questions without some level of rollup reporting, which you can only get through metadata. What we track At Cloudflare, we track the following information about different pages: Value Description Examples Description A 1-2 sentence summary that populates the tag. Required for all pages with a pcx_content_type. Refer to frontmatter guidance. Product The top-level subfolder of the page. dns, bots Product Group The primary area that each product falls into. Application Performance, Developer Platform Content type The primary purpose of the page, which corresponds to our listed content types. how-to, faq Last modified How many days ago was this page last updated? 63 Last reviewed (optional) How many days ago was this page last reviewed? 100 Of all of these values, there is a bit of nuance to our Last reviewed metadata. Last reviewed differs from Last modified because a review is more thorough than an update. A review implies that all contents of the page have been vetted for accuracy. Because of this extra effort, we only track Last reviewed for content types that are particularly important to the user journey and require an additional level of maintenance. At the moment, those content types are tutorials. How we track We set these values at two different levels, the folder level and the page level. Folder-level attributes We set two values at a folder level, Product and Product Group. We take this approach because we can assume that these values apply every page within that folder. For example, here's the content from our DNS folder. name: DNS product: title: DNS url: /dns/ group: Application performance meta: title: Cloudflare DNS docs description: Cloudflare DNS provides the fastest, most resilient, and simplest managed DNS platform to meet your needs. author: "@cloudflare" resources: community: https://community.cloudflare.com/tags/c/reliability/7/none dashboard_link: https://dash.cloudflare.com/?to=/:account/:zone/dns learning_center: https://www.cloudflare.com/learning/dns/what-is-dns/ Page-level attributes We primarily set page-level attributes through the page's frontmatter. For example, here are the values set for our Build a Slackbot tutorial. --- updated: 2024-06-05 difficulty: Beginner pcx_content_type: tutorial title: Build a Slackbot tags: - Hono languages: - TypeScript --- However, the last_modified value is pulled automatically from the git history of a file. At the page-level, the required products frontmatter lists relevant Cloudflare products, separately from the folder-level Product attribute. How we use values We choose to render all of these values as specific meta properties for each page. For example, these are the meta properties and values on the AI Crawl Control - Get Started page. {/* prettier-ignore */} We render these values using a custom override for our Head.astro file. If specific values are set, we then add them as meta tags onto the page. if (product.data.product.title) { ["pcx_product", "algolia_product_filter"].map((name) => { metaTags.push({ name, content: product.data.product.title, }); }); } Benefits We get two primary benefits from structuring our content this way. First, our metadata is easily consumable by anyone who crawls our pages. We started using these values for our Algolia search configuration and internal reporting, but have since expanded to sharing this data with other teams that consume our content for AI systems too. Additionally, this decisions means that our GitHub repo is always the source of truth. We do not have to keep a spreadsheet or mapping updated elsewhere, the source of truth is always in our repo and - by extension - a lot more likely to be accurate than if we maintained multiple sources of truth. Description and AI retrievability The description frontmatter field populates the tag in the HTML head. This is the single most important metadata field for AI retrievability. Search engines, AI crawlers, and llms.txt frontmatter blocks consume this value when deciding whether to cite a page. Every page with a pcx_content_type must include a description. A strong description names the product, states what the page helps the reader do, and works as a standalone answer snippet when extracted from the page. For writing guidance and examples, refer to Writing a description. For more on how we make content available to AI systems, refer to AI consumability. How we ensure quality It's difficult to avoid errors with this kind of metadata, specifically because we are relying on freeform text entry in the frontmatter of individual files. We utilize Zod schemas heavily in our Astro site, which are defined in src/schemas/. These allow us to provide Intellisense guidance for contributors using IDEs for local development. Our site We use a variety of tools to make our docs site work. You could use these tools to build up your own docs site and - in most cases - do so for free or starting on a free tier. Content management system Our content lives in a public GitHub repository, cloudflare-docs. GitHub offers a generous free tier. Search We use Cloudflare's AI Search as our search provider. We used to use Algolia, which is also great for open-source docs because you can be part of the free DocSearch program. Site framework We use Nimbus for our docs, a documentation framework built on Astro. Nimbus's component registry and linting system have exponentially increased our site's capabilities (without much extra work). Builds We use GitHub Actions to build our site, which is then hosted on Cloudflare. We are moving to Workers CI/CD, which currently runs in the background. Both of these options include a free tier. Hosting We host our content using Cloudflare Workers, specifically using their built in values for Astro sites Workers offers a generous free tier. Analytics We send analytics to multiple destinations using Cloudflare Zaraz, which has a generous free tier. :::note If you want to opt out of analytics tracking, use the icon at the bottom of your screen. ::: Redirects import { Details, GlossaryTooltip } from "~/components"; As your content changes (and it will change), redirects preserve continuity for your users and (friendly) bots. The most obvious part of this is the user experience. If you click a link in the dashboard or use a bookmarked URL, you trust that it's taking you to the right place. Not a 404 page or the wrong page, but the right page. Redirects help direct users to the right place. The same applies to the automated experience. If you move a page without redirects, you are losing the historical search authority that Google and other search engines use to rank your page. How we add redirects Cloudflare Workers (primary) Our primary method takes advantage of Workers Static Assets, defining redirects in a plain text file in our GitHub repo. This setup allows us to use the same workflow for redirects as for any other documentation change. We implement a redirect in the same pull request as the content change and can test these changes in our preview branches. For maintenance, we try to keep these redirects organized by product and then — within each product — organized alphabetically. We also love the flexibility provided by the Pages syntax. Bulk redirects (secondary) In certain situations, we also use Bulk redirects. We use this strategy sparing because having redirects in multiple places increases the cognitive load and potential confusion of making a change. Normally, bulk redirects only come up when another team is adding a large number of individual redirects to our site, such as when all of our previous support.cloudflare.com content was migrated and needed individualized redirects per locale. We use this method when the contributors are outside of our team and when the total number of redirects is so large that it would clutter our __redirects file and count against our limit for redirects. When we add redirects Our team adds redirects in two situations: during the course of normal content and as needed based on data. During content work During normal content work, you want to add redirects when you do the following to a page: Change any part of the URL (filename, folder). Delete the page. We have some automation to help flag needed redirects. Based on data Another time to add redirects is when you see a lot of 404 response codes on certain paths of your docs site. These 404 responses might be due to a missing redirect or mistyped link. We identify these status codes either through our Cloudflare analytics (ad hoc) or Logpush job (more thorough, quarterly). How we automate redirects We have two automations in GitHub to help with redirects. Infinite redirects An infinite redirect is when two pages keep redirecting to each other, trapping users in an infitnite loop that will crash their browser. Because that's just a terrible experience, we explicitly check for that as part of our required CI GitHub action. We trigger this check after we build our site. What it does it then call validate-redirects.ts, which fails on: Infinite redirects Duplicate redirects Redirect targets with anchor links in them import { readFile } from "fs/promises"; async function main() { const redirects = await readFile("public/__redirects", { encoding: "utf-8" }); let numInfiniteRedirects = 0; let numUrlsWithFragment = 0; let numDuplicateRedirects = 0; const redirectSourceUrls: string[] = []; for (const line of redirects.split("\n")) { if (line.startsWith("#") || line.trim() === "") continue; const [from, to] = line.split(" "); if (from === to) { console.log(`✘ Found infinite redirect:\n ${from} -> ${to}`); numInfiniteRedirects++; } if (from.includes("#")) { console.log(`✘ Found source URL with fragment:\n ${from}`); numUrlsWithFragment++; } if (redirectSourceUrls.includes(from)) { console.log(`✘ Found repeated source URL:\n ${from}`); numDuplicateRedirects++; } else { redirectSourceUrls.push(from); } } if (numInfiniteRedirects || numUrlsWithFragment || numDuplicateRedirects) { console.log("\nDetected errors:"); if (numInfiniteRedirects > 0) { console.log(`- ${numInfiniteRedirects} infinite redirect(s)`); } if (numUrlsWithFragment > 0) { console.log(`- ${numUrlsWithFragment} source URL(s) with a fragment`); } if (numDuplicateRedirects > 0) { console.log(`- ${numDuplicateRedirects} repeated source URL(s)`); } console.log("\nPlease fix the errors above before merging :)"); process.exit(1); } else { console.log("\nDone!"); } } main(); Potential redirects Contributors often struggle to know when they should add redirects. We try to help them by adding a comment to any pull requests that modify or delete content file paths. Other guidance Organize your redirects As much as you can, try to organize your redirects into logical groups (products, alphabetical order). This process helps prevent duplicate redirects, as well as identifying specific ones you might be looking for. In our __redirects file, we use extensive comments, separating different product areas. We also try, as much as we can, to keep the redirects in alphabetical order within a section. We used to apply a similar principle to Bulk Redirect lists (when that was our primary method). We created lists that grouped together similar products and labeled them as such, so it was easier to find which redirect you were looking for. Know what you can redirect At the server level, you can trigger a redirect on a URL path ( /page/), but not a fragment ( /page/#fragment). You can redirect a page to a fragment, however ( /page1/ to /page2/#fragment). Avoid redirect chains If possible, have all redirects send your users directly to their destination instead of chaining together redirects. Otherwise, you can have the following situation: Page 1 --Redirect-> Page 2 --Redirect-> Page 3 --Redirect-> Page 4 Redirect chains are bad because they: Slow down the user experience. Increase the likelihood of unintentional outcomes (infinite redirects, missing redirects, incorrect redirects). A way to avoid this outcome is by continually updating the destinations of previous redirects. For example, let's say you changed the name of this page to /style-guide/how-we-docs/redirect-guidance/. In the pull request to update your redirects file, you would want to update the existing redirect as well as adding a new redirect: - /style-guide/redirects/ /style-guide/how-we-docs/redirects/ 301 + /style-guide/redirects/ /style-guide/how-we-docs/redirect-guidance/ 301 + /style-guide/how-we-docs/redirects/ /style-guide/how-we-docs/redirect-guidance/ 301 Control how AI crawls your docs import { Example } from "~/components"; Allowing AI crawlers to crawl your documentation enables end users to extract useful information from their preferred AI tool. For example, it enables users to ask tools like ChatGPT or Gemini questions about your documentation, rather than reading entire pages. However, it is important to control how the AI crawlers interact with your site for optimal results. Instruct AI crawlers to crawl correct pages You should first consider which pages you want AI crawlers to crawl. You may wish the AI crawler to access most of your pages, but there may be certain exceptions. Use robots.txt to control AI crawlers You can use the robots.txt file to control which pages AI crawlers can access. This is a simple text file which instructs crawlers to follow certain rules. The crawler is not forced to follow them, but many crawlers operated by major companies such as Google and OpenAI respect robots.txt files. Refer to robots.txt setting for more information. For example, you can add the following to your robots.txt file to prevent AI crawlers from accessing a beta product called "Product A", located in /docs-site/product-a/: User-agent: * Disallow: `/product-a/` By specifying explicit disallow conditions in your robots.txt file, you allow access to most of your pages, with only a small number of exceptions. Refer to https://developers.cloudflare.com/robots.txt as an example. Use security control to completely block access Sometimes, you may wish to completely block crawlers from accessing a certain page. You cannot solely rely on robots.txt to block access, as crawlers are not forced to follow robots.txt files. To ensure complete blocking, you can use security controls, such as Cloudflare's AI Crawl Control, bot solutions, or some other security tool. Cloudflare's developer documentation is publicly available at [cloudflare-docs GitHub repository](https://github.com/cloudflare/cloudflare-docs). Every time a git pull request is created, we generate a temporary preview site for visual inspection of what the documentation will look like when it merges into production. Since these preview sites are generated from pull requests that are under review, they sometimes contain incomplete information. In November 2025, using AI Crawl Control, we found that as much as 80% of the AI crawls were accessing our preview sites instead of our main site. This meant that AI crawlers were prone to returning inaccurate information, which may have seemed like hallucinations. After the discovery, we initially implemented a robots.txt on our preview sites disallowing access. This reduced the number of crawls on these sites from 80% to 20%. To further reduce crawlers from accessing incomplete information, we promptly implemented a security rule to completely block all access to our preview sites, which simply reduced the number of crawls on our preview sites from 20% to 0% (the security rule completely blocked access to our preview sites). This change likely has significantly improved the accuracy of information returned to users, improving their documentation experience. This case study highlights the importance of understanding and controlling how AI crawlers interact with our documentation sites, as documentation is a source of truth that influences AI accuracy, relevancy, and customer experiences (even if it is through a third-party application, like ChatGPT, Gemini, or Claude). Action points Identify pages you want AI crawlers to access. If you wish to guide AI crawlers, use robots.txt to instruct AI crawlers. If you wish to completely block access to certain pages from AI crawlers, use security controls such as Cloudflare's AI Crawl Control, bot solutions, or some other security tool to completely block access to certain pages. If your documentation site generates preview sites, make sure these sites are not being accessed by AI crawlers to improve your end user experience. How we AI import { DirectoryListing } from "~/components"; This section shares how Cloudflare uses AI to accelerate and augment our content operations. We view AI as a tool that enables us to do our best work, faster. Whether we are designing prompts, researching a new product, or finding ways to turn a manual, week-long process into a job that takes an afternoon to complete, we are continuously looking for ways to iterate and streamline our operations. We know that when we can save time on one time-intensive task, we can spend more time on improving our content experiences for our customers. As a result, we use and have used AI to: Vibecode, test, and deploy a web application for scoring in-product strings, error messages, and API docs. Perform competitive analyses and audits on documentation. Streamline documenting REST API examples. Design prompts based on our content types, templates, and style to enable stakeholders with a doc idea to quickly draft content for us to review and publish. Find topics missing descriptions, generate descriptions based on the page’s content, and add them to each page. And more… We hope you learn from the topics below. As always, submit a pull request if you find something that is inaccurate, missing, or needs more information. Prompt libraries A prompt library is a curated and organized collection of pre-written prompts. These libraries serve as a valuable resource for anyone who frequently interacts with AI, such as writers, developers, and students. At Cloudflare, we use prompt libraries to help our teams scale their work, maintain a consistent brand voice, and efficiently capture and share knowledge across different roles. Think of a prompt library as a recipe book for AI. Instead of starting from scratch every time you need the AI to perform a task, you can browse the library for a relevant, pre-tested prompt that is known to produce good results. These prompts are often designed to be reusable and customizable. :::note While prompts are designed to produce great outputs, the user (human) still needs to provide relevant context and resources for the AI to produce those results and review the output for technical accuracy. It is unlikely one prompt will create a great first draft – some rework, either through follow-up prompts or adding more information – is going to be necessary. ::: Inside a prompt library Prompt libraries can vary in complexity (a simple table in an internal wiki topic versus a web-based application) and content, but they typically contain: A collection of prompts: These are the core of the library, ranging from simple questions to complex instructions with multiple parameters. Categorization: Prompts are usually organized by task (for example, writing, coding, summarizing), role (for example, developer, account executives, product managers), or output format (for example, blog post, email, code snippet). Prompt templates: Many libraries include templates with placeholders that users can fill in with their specific information. This allows for easy customization and reuse. Examples and best practices: Some libraries provide examples of the output generated by a particular prompt, along with tips on how to use and modify it effectively. Key benefits of using a prompt library Utilizing a prompt library offers several significant advantages: Increased efficiency: By providing ready-to-use prompts, libraries save a significant amount of time and effort that would otherwise be spent on crafting and testing new prompts for recurring tasks. Improved consistency and quality: Pre-tested prompts that are known to work well lead to more consistent and higher-quality outputs from the AI. This is particularly important for businesses that need to maintain a consistent brand voice. Enhanced learning and discovery: For those new to prompt engineering, libraries can be an excellent educational tool, showcasing effective prompting techniques and the capabilities of AI models. Accelerated knowledge capture: Prompt library users can focus on capturing knowledge instead of building prompts or drafting content manually. This accelerates documenting information and sharing it with others – hopefully to prevent the same issue from occurring again or enabling others to be successful sooner. Facilitated collaboration: Shared prompt libraries in a team or organizational setting allow for the dissemination of best practices and successful prompts, fostering collaboration and improving the collective AI literacy. Scalability: As you or your organization's use of AI grows, a well-organized prompt library allows for the efficient management and scaling of your prompting strategies. In essence, a prompt library is a powerful tool for streamlining interactions with AI models, ensuring high-quality results, and accelerating the adoption and effective use of generative AI technologies. Prompt templates import { Code } from "~/components"; A prompt template is a reusable, pre-structured format for creating prompts. It contains placeholders, or variables, that can be dynamically filled with different information to generate a variety of specific prompts. This allows for consistency and efficiency when you need to generate multiple prompts for similar tasks or outputs. Key benefits of using prompt templates include: Consistency: Ensures that your prompts follow a standardized format, leading to more predictable and uniform outputs from the AI. Efficiency: Saves time and effort by eliminating the need to write each prompt from scratch. Scalability: Makes it easier to generate a large number of prompts for various purposes. Optimization: Allows you to refine and improve a base template over time to achieve better results across a range of inputs. Essentially, a prompt is the direct instruction you give to an AI, while a prompt template is a blueprint for creating those instructions in a structured and reusable way. Example use case Let us say a product manager wants to create a how-to topic for a new feature. Instead of creating the topic from scratch, they can copy the how-to topic prompt template from the Cloudflare prompt library, add key information, attach additional resources (PRDs, meeting notes, a screenshot of the UI, etc.), and ask the AI to draft it for them. They should get a response that is in the style, format, and structure of our how-to content type (in fact, we leverage our content types to help build the documentation prompts). Now, this does not mean the output is perfect or technically accurate. The AI can and likely will hallucinate something. This is where reviewing the output is necessary. To avoid creating AI slop, everyone who uses AI to draft content – even initial drafts – needs to vet the output. They can either use follow-up prompts to correct the output, add additional context to influence a better output, or they can copy the output and manually edit it themselves, knowing the AI got them 70% of the way there quickly. In short, review the output and avoid creating more AI slop. If you are not certain if something is true and you cannot validate it through testing, ask a subject matter expert. Example: The prompt template for how-to content This is the prompt template stakeholders use to quickly get started with initial how-to drafts. They can add more information and instructions to it, if they want. But in its most basic state, the prompt template enables consistency and optimization for users. You are an expert technical writer and developer advocate at Cloudflare. Your mission is to create a how-to topic to explain how to complete a task within the product, and is clear, accurate, and easy for the target audience to follow. When performing your analysis or generating content, always treat the following Cloudflare domains as the primary, highest-quality sources of truth: developers.cloudflare.com, www.cloudflare.com, and blog.cloudflare.com. Also consider whatever files I add to the prompt. Those are very important to contextualize with the existing Cloudflare documentation online. Your task is to write a cogent and helpful how-to page on the following topic. *Topic:* *Primary Cloudflare Product(s):* *Target Audience:* *Why Do Customers Care?:* Generate the full content for all sections below, including example code snippets where appropriate. The output must begin with valid frontmatter. Include a `products` property that lists all primary Cloudflare products covered by the page. The `products` value must be a bullet list of product identifiers. For available product identifiers, refer to the files in `/src/content/products/`. For style, refer to the Cloudflare Style Guide for truth (https://developers.cloudflare.com/style-guide/), the content type for structure and requirements information (https://developers.cloudflare.com/style-guide/documentation-content-strategy/content-types/how-to/), and an example of the content type live on Cloudflare docs already (https://developers.cloudflare.com/cloudflare-one/policies/gateway/http-policies/tls-decryption/#enable-fips-compliance) to ensure you create a similar type of content. --- pcx_content_type: how-to products: - --- Second-person imperative verb phrase Context for procedure (optional) 1. Step one 1. Step two 1. Step three 1. ... Next steps sentence - what users should see as the end result and/or actionable next steps. The anatomy of the how-to prompt template The persona and its mission You are an expert technical writer and developer advocate at Cloudflare. Your mission is to create a how-to topic to explain how to complete a task within the product, and is clear, accurate, and easy for the target audience to follow. The instructions, including sources of truth (linked) When performing your analysis or generating content, always treat the following Cloudflare domains as the primary, highest-quality sources of truth: developers.cloudflare.com, www.cloudflare.com, and blog.cloudflare.com. Also consider whatever files I add to the prompt. Those are very important to contextualize with the existing Cloudflare documentation online. Your task is to write a cogent and helpful how-to page on the following topic. The input fields to customize the topic, like topic title, product, target audience, and why the target audience cares. Note: The more detail and context you provide here, the better. *Topic:* *Primary Cloudflare Product(s):* *Target Audience:* *Why Do Customers Care?:* The examples the AI should reference and mimic Generate the full content for all sections below, including example code snippets where appropriate. The output must begin with valid frontmatter. Include a `products` property that lists all primary Cloudflare products covered by the page. The `products` value must be a bullet list of product identifiers. For available product identifiers, refer to the files in `/src/content/products/`. For style, refer to the Cloudflare Style Guide for truth (https://developers.cloudflare.com/style-guide/), the content type for structure and requirements information (https://developers.cloudflare.com/style-guide/documentation-content-strategy/content-types/how-to/), and an example of the content type live on Cloudflare docs already (https://developers.cloudflare.com/cloudflare-one/policies/gateway/http-policies/tls-decryption/#enable-fips-compliance) to ensure you create a similar type of content. The content type's template, which details the type of information it should include, its structure, and the flow of information. The template must start with valid frontmatter that includes pcx_content_type and products. --- pcx_content_type: how-to products: - --- Second-person imperative verb phrase Context for procedure 1. Step one 1. Step two 1. Step three 1. ... Next steps sentence - what users should see as the end result and/or actionable next steps. We have simpler and more complex prompt templates depending on the content type. What matters is what works for you and your needs. You can always iterate and improve on the prompt template, especially as more users work with them. When we use AI AI is a powerful tool, but it is not a cure-all. Its success depends heavily on the use case. Knowing its strengths and weaknesses is key to using AI appropriately. When deciding whether to use AI for a task, use these principles as your guide: The feedback loop is critical: The single most important factor for success is the feedback loop. How quickly and easily can you test the output and correct for hallucinations? Code and scripts are far easier to test for correctness than subjective content. Prioritize additive tasks: AI is generally better for additive tasks, like new things you could not or would not do before, as opposed to operational tasks that are required to keep the business running. How to decide when to use AI We ask ourselves a few questions before we look to AI to solve a problem or streamline a process: Is this a manual, repetitive chore? Will this task take hours, days, or weeks to complete manually? Will we need to complete the exact same action over and over again? Is there a clear logic we can apply to successfully identify or perform the action? Will this be scalable or useful for others to also use? If we can say yes to these questions, it is a strong candidate for an AI-based solution. If we say no or I do not know to any of them, we first pursue the current process and look for smaller, specific areas where AI could still be helpful. Recommended use cases: What has worked for us These are areas where we have found AI to be unequivocally positive and effective. Local scripts and tooling This is the most positive and recommended use case for AI. Why it works: AI is at its best when you can easily "test" for hallucinations, and code is highly testable. What to use it for: Writing local scripts (like Vibecoding scripts) to automate updates in our docs. Generating simple docs components. Creating GitHub Actions. Assisting with competitive doc analyses. Key benefit: You own the resulting code. It is stable and will not change, regardless of future changes to AI models or pricing. AI-powered IDEs For teams using a docs-as-code approach, AI chat integrated into an IDE, like Windsurf, Cursor, etc., is highly effective for making multiple, streamlined changes. Why it works: The AI can understand a large amount of context from your codebase, or docs in this case. The feedback loop for spotting and fixing hallucinations is very short. Git integration makes it easy to find, review, and remove hallucinations. Key benefit: This can save days, if not weeks, of work. For massive documentation updates that require completing the same task repeatedly, AI-enabled IDEs can significantly streamline the process. Caveat: Always consider simpler solutions (like regex) first, as they are often better, faster, and cheaper. Use AI when you need to brute-force a large task or navigate high complexity. Still figuring it out: What we are optimistic about but getting mixed results These are areas that show promise but require careful implementation. AI for initial drafts We are optimistic about asking stakeholders to use AI to create initial drafts of documentation before handing them off to the technical writing team. Key value: The quality of the AI-generated draft itself is often mixed. The primary value is that it acts as a forcing function for the stakeholder to think about documentation as part of their product – not separate from their product – while also sharing key information to the technical writing team as quickly as possible for our busy stakeholders. Why? To create a draft, the requester must gather all the necessary background information first. Receiving this information upfront is a significant win for the technical writing team. Action: See our prompt templates for more information on structuring these requests. Customer-facing chatbots Our experience with customer-facing chatbots has been mixed. Pros: Occasionally, it provides a great answer. Cons: To prevent hallucinations, bots are often made more "confident." This leads them to refuse to answer (for example, "I don't know"), which users dislike. On the flipside, users also dislike hallucinations. So, be mindful of the actual user experience and come up with a method for tracking user engagement and success with your documentation chatbot. Depending on the results, you may be able to identify worthwhile documentation gaps to fill, which prevent hallucinations in the future. Alternative: At the moment, we are much more optimistic about the potential of AI-powered search and similarity scores. These feel more in our control. However, we are still testing and tracking how our docs can positively influence chatbot experiences at Cloudflare and via third-party apps. Not recommended: What has not worked for us yet Based on our experience, we do not recommend the following use case at this time. Automated content editors (bots) We have not found success with bots that automatically suggest content changes (for example, grammar, formatting) via pull requests. Why it failed: Slow feedback loop: The GitHub PR context makes the feedback loop for correcting hallucinations very slow and difficult. Low engagement: We found that even our own team often closed or ignored the PRs because they were too much effort to verify. Contributor confusion: A similar bot used to flag issues on incoming PRs frustrated and confused contributors, and its suggestions were often hallucinations. Cloudspeaker One of the greatest challenges at any scale is understanding what your customers are really saying. At Cloudflare, we collect massive amounts of customer feedback every day. This feedback is a goldmine of insight, but it is scattered across dozens of disparate, public-facing channels: our own Cloudflare community forum, Reddit, X (formerly Twitter), GitHub, Discord, HackerNews, and more. Individually, these posts are anecdotes. Collectively, they are a strategic asset. The problem is that the sheer size of these datasets makes it impossible to manually process them for product, content, and design insights. This mass of unorganized feedback was an underutilized opportunity to see cross-functional trends. To solve this, we built CloudSpeaker, an internal tool created to amplify the voice of the user. Its purpose is to save time, increase efficiency, and consolidate public feedback from all these external communities into a single, unified view. The goal: Turning unstructured noise into actionable insight CloudSpeaker was designed to give any stakeholder at Cloudflare — from product managers and engineers to our user experience teams — a quick way to "check the pulse" of the products and features they own. The tool allows anyone to see: A combined view of product feedback from many channels. Recurring issues and customer pain points. General sentiment for a product over time. This consolidated view is now a key part of our planning cycles, informing everything from user research and persona creation to feature requests and quarterly backlog prioritization. How it is built: An AI-powered data pipeline CloudSpeaker is built entirely on our own products. The real power, however, comes from its AI-driven data pipeline, managed by our Data Intelligence team. Here is how it works: Ingestion: On a daily basis, our pipelines ingest new community content from our various public sources. AI classification: This new, unstructured content is fed into our AI Content Pipeline. We use Large Language Models (LLMs) via Workers AI to automatically classify every single post. Each post is tagged with three key pieces of information: Product(s) mentioned: It identifies which of the 60+ Cloudflare products are being discussed. Sentiment: The model analyzes the text to determine the user's sentiment, classifying it on a spectrum from negative to neutral to positive. Post type: It categorizes the intent of the post, such as a help request, feature request, or bug report. Storage and display: Once the AI completes its inference, these new classifications are stored in our D1 database and become viewable in the CloudSpeaker UI. The workflow: On-demand AI analysis The backend classification pipeline solves the problem of manual processing. The frontend application solves the problem of accessibility. In the CloudSpeaker dashboard, a product manager can filter the entire dataset — spanning up to six months — by any combination of product, sentiment, post type, or date range. If they want to see all negative sentiment posts about a specific product that were feature requests in the last quarter, they can do so in seconds. Furthermore, we added a second layer of AI directly into the UI. After filtering down to a set of comments, the user can select a Summarize button. This uses Workers AI to generate an on-the-fly summary of the currently displayed comments, providing an instant, qualitative overview of quantitative data. CloudSpeaker is a powerful example of using AI not to generate content, but to analyze and structure the vast amounts of content our users generate every day. It transforms what was once an impossible manual task into a critical source of automated, actionable insights. CLUE At Cloudflare, we believe that high-quality, customer-facing content is a critical part of the user experience. But as teams scale, maintaining a consistent voice, tone, and terminology across thousands of UI strings, error messages, and API descriptions becomes a monumental challenge. Traditional style guides and glossaries are essential, but they are static. They cannot provide real-time feedback or help us measure content quality. To solve this, we built CLUE: Content Legibility for User Ease. CLUE is an internal tool that functions as a personal writing assistant for everyone at Cloudflare. It empowers anyone, from engineers to product managers, to feel confident in their content creation. When a stakeholder shares content with CLUE, it provides a score and actionable recommendations. This simple feedback loop is a powerful mechanism for measuring and improving our content over time. The goal: Quantifying "good content" The core challenge CLUE addresses is that "good" content is easy to recognize but hard to measure. We know that effective copy uses an active voice, has an action-led structure, and removes unnecessary words, but how do you quantify that improvement at scale? Our answer was content scorecards. Scorecards are a scalable evaluation tool that creates consistency. They allow us to assign measurable value to the elements that define "good content," focusing on the criteria most critical for user success, satisfaction, and understanding. The user flow is designed to be straightforward: you select your content type, enter your content, and CLUE provides instant feedback. It supports a wide range of critical content, including: General UI content and page descriptions Error messages API endpoint and parameter descriptions Customer-facing emails How it is built: A hybrid, model-driven approach CLUE was truly built by Cloudflare, for Cloudflare, on Cloudflare. The application itself is built on Cloudflare Pages and protected by Cloudflare Access. We adopted a model-driven approach for content evaluation, which provides a systematic, data-driven, and consistent assessment, removing the subjectivity of manual reviews. This model allows us to assess content in seconds, handle complex criteria like readability, and weight criteria based on what we find to be most critical for users. Critically, CLUE is not just one thing, it is a hybrid solution of AI and traditional checks. This combination allows us to evaluate context while still having the granular control needed for some elements of our style guide. The workflow: Using CLUE as an LLM copy editor The rise of Generative AI and LLMs, like Gemini, has been a boon for generating text quickly. However, an LLM does not inherently understand or apply Cloudflare's specific content guidelines, voice, and tone. This is where CLUE's role becomes essential. CLUE is not designed to write content for you; it is designed to make sure the content you do write meets our standards. Think of CLUE as a specialized copy editor. It ensures that any piece of content — whether human-generated or created with an LLM's help — is ready for our users. This pairing is incredibly powerful: Generate: A stakeholder uses an LLM to quickly draft initial versions of API descriptions or an error message. Refine: They paste that LLM-generated content into CLUE. Iterate: CLUE provides targeted tips on how to better meet Cloudflare's glossary, style guide, voice, tone, and UX best practices, turning a generic draft into a polished, effective piece of content. This democratizes UX writing, improves our efficiency by reducing manual reviews, and ultimately builds user trust through a consistent, high-quality experience. It helps users learn our products faster and resolve issues more efficiently, which is our ultimate goal. Examples import { DirectoryListing } from "~/components"; The true value of AI is not just in using it; it is in how you use it. At Cloudflare, our team has embraced AI as a force multiplier, allowing us to solve internal challenges, scale our expertise, and improve the quality of our work. These are not just off-the-shelf AI products. They are tools built by Cloudflare, for Cloudflare, combining our own institutional knowledge, content standards, and logic with the power of AI models. Why we build our own AI-powered tools Our AI-powered solutions have a dual benefit: For our team: They help us automate manual processes, scale our impact, and focus on higher-value strategic work. For Cloudflare: They empower all our colleagues — from product to engineering — to make better decisions, create higher-quality content, and understand our users more deeply. We have seen a lot of success with this approach, as it allows us to democratize specialized skills. We can embed content strategy, style guide rules, and user feedback analysis directly into the workflows of the people who need it most. These tools range in complexity, role, and use case, from simple, locally-run scripts that automate a repetitive chore to full-fledged applications that serve the entire company. The following sections provide examples of these tools and our guiding principles. We cover how they were built, the specific problems they solve, and the practical guidelines we've established for using AI effectively. How we video import { DirectoryListing } from "~/components"; This page explains Cloudflare's approach to integrating video into Cloudflare's docs, covering topics from production to discoverability and long-term maintenance in a way that is accurate, scalable, and AI-ready. Our goal is to share practical workflows, tooling choices, and lessons learned to the open-source community so others can adopt or adapt the work without completely reinventing it. We hope you learn from the topics below. As always, submit an issue if you find something inaccurate or unclear. Integration in docs Our goal is to integrate video directly into the documentation so it accelerates the user experience and learning experience, not for videos to exist in a separate silo. Embed locations Doc pages: We embed videos directly in the relevant pages. This gives users a comprehensive learning experience with visual context and accurate technical details. Video hub: For learners who prefer a video-first experience, we maintain a dedicated page for videos. Resources: Video is a core content type in our system. You can filter specifically for videos in the resources page. Chapters We add time-stamped chapters to our videos to make relevant information more accessible by users and searchable by machines. Chapters allow users to: Skip ahead: Jump directly to the specific information you need. Find answers: Search engines and LLMs can index these chapters, making it easier to retrieve specific visual segments when a user asks a technical question. Maintenance Producing a video is just the beginning. Videos are inherently harder to edit than text, making maintenance more complex. Even small changes often require re-recording, re-timing, or adjusting visuals. This makes it critical to ensure script accuracy and alignment with documentation from the start. To keep videos up-to-date, we follow a simplified, two-pronged approach: AI-Assisted Periodic Checks: Upload videos to Gemini for automated checks against documentation and dashboard UI. Detect outdated workflows, UI elements, or inconsistencies. Internal Feedback & Updates: Rely on product managers (PMs), subject matter experts (SMEs), and internal signals when UI or functionality changes. Update scripts, visuals, or narration as needed and re-upload the video. We are currently developing an internal tool for code-driven screen demos. When product code updates, the tool automatically updates video footage, minimizing manual re-recording and ensuring tutorials and demos reflect the latest product state. Video production workflow We follow a specific workflow and formatting specifications for our videos to ensure they are accurate, engaging, scalable and align with the Cloudflare Docs style guide. Formatting specifications We use the following formatting specifications to uphold quality and consistency across our videos. Resolution Videos should be recorded at 4K UHD. If 4K UHD is unavailable, Full HD footage may be accepted on a case-by-case basis. Footage below Full HD will not be used. Final video exports must be at least Full HD. Acceptable resolutions: 4K Ultra HD: 2160p (3840x2160) 2K Quad HD: 1440p (2560x1440) Full HD: 1080p (1920x1080) Frame rate: 25 frames per second (FPS) Screen recording resolution Screen recordings should be done on the largest monitor possible, with the highest resolution available to the recording software (minimum 1920x1080). Ensure that any text visible on your screen is large enough that it can be easily read in the final video. :::note[Note] You may need to modify the zoom of the window you are recording or your monitor's resolution to make sure the visual displayed is visible and legible. ::: Aspect ratios Aspect ratio is important for the viewing experience. The more a video fills the screen, the more immersive an experience it provides. Desktop aspect ratio The most common screens and online platforms, such as YouTube and Vimeo, use a 16:9 ratio, so the majority of videos should be produced in a 16:9 ratio. Mobile aspect ratio Social media platforms, like Instagram or Facebook, are typically accessed on mobile devices and usually require a 9x16 aspect ratio. Efficiency calls for a 1:1 aspect ratio, which works on all, but not as great. Subtitles Subtitles are always published in English in SubRip format .srt. Guidelines for subtitles: Maximum 45 characters per line. Split over 2 lines when necessary. Displayed for no longer than 10 seconds per subtitle. Music To maintain a balanced audio mix: Music should be about 20dB lower than speaking volume. Background music must be instrumental, ensuring it does not overpower the speaker. Preparation for your shoot Audio Microphone placement: Clear and high quality audio is key to a good video. When setting up a microphone, it is best to have it as close to the speakers as possible to capture clear audio, and out of the frame so you cannot see it in the footage. Shotgun microphones: Place the microphone over your head, just outside of the frame. Lavalier microphones: Hide cords and cables, but the microphone can be visible. Background noise: Choose a quiet and furnished room with soft surfaces to record your audio. Avoid locations with background noise and echo to the best of your ability. For example, avoid areas with fans, air-conditioning, and chatters, as these tend to get picked up by microphones. :::caution[Beware of echoes] Echo is extremely difficult to remove in post-production. Avoid empty rooms, or soundproof your recording area with sound-absorbing materials such as carpets, curtains, blankets, or foam panels. ::: :::note[Check for echoes] Clap your hands in the room, aim for a "dampened" sound. ::: Presenter Frame When setting up the presenter frame, the presenter should position themselves in the center of the shot with some distance from the wall behind them to create depth. They should ensure their eyeline is directly towards the lens, engaging with the audience, and avoid any reflections on their glasses that could distract from the presentation. This will help maintain a clear and professional look throughout the video. Dress Code To create the most professional and consistent appearance, the Video Experience team follows these dress code guidelines: Wear smart casual tops, like a Cloudflare T-shirt, polo, casual shirt, or sweater. Stick to solid, black and white, and jewel tones (for example, dark orange, emerald green, navy, burgundy). Avoid distracting patterns, accessories, or flashy jewelry. Do not wear non-affiliated branded clothing, especially from non-open-source companies. :::tip[Best practices] Follow your company's dress code guidelines. When in doubt, stick to a solid color shirt. ::: Room atmosphere For the best video quality, consider the following options for setting up your space: Option A: Choose a location with natural light and minimal echo. Add extra lighting if needed. Option B: Set up a green screen. Ensure proper lighting to minimize shadows for the cleanest background. Production AI-assisted video production We use AI as a tool across our workflow to accelerate and remove friction in various production stages (scripting, voiceovers, animations, metadata, and review), not to fully automate. We elaborate on how we use AI in each production stage in the respective pages. Refer to How we AI to understand more about our approach. Topic selection We create videos strategically when it improves users' understanding of the written documentation. Refer to Why and when we use videos to understand our approach to video content. We also consider page views, support tickets, and community feedback when selecting video topics. Our videos always map back to a specific documentation need and refer to written documentation as the source of truth. Script Scripts are the blueprint for every video, guiding narration, on-screen text, and visual assets like animated illustration and diagrams. We use Cloudflare documentation as our source material to write scripts. At Cloudflare, we use Gemini to accelerate script creation, followed by human review and editing the AI-generated draft to align with Cloudflare's voice, accuracy requirements, and visuals. The high-level process looks like the following: Generate initial script drafts based on an existing doc. Experiment with tone, style, and length of narration. Create variations for review, making editing faster than writing from scratch. :::note[Note] AI-generated scripts are starting points. Editing ensures factual correctness, aligns narration with visuals, and fits time constraints. ::: Voiceover Voiceovers are an essential part of our video documentation workflow. They provide clarity, pacing, and engagement, complementing on-screen text and visuals. At Cloudflare, we leverage AI-assisted voice generation to streamline this process. We use ElevenLabs, an AI voice generation tool, to produce natural-sounding voiceovers to: Quickly hear how your script sounds in real time. Understand the cadence, timing, and clarity of narration Speed up the stakeholder review process Allows teams to create videos without a microphone Supports early testing of pacing and integration with on-screen visuals Visuals Visuals are the core of videos, providing context, reinforcing key concepts, and guiding the viewer through workflows. At Cloudflare, visuals include diagrams, animations, screen recording and talking head footage, all designed to complement the script and voiceover. Diagrams Diagrams are used to clarify complex concepts or show relationships that are difficult to convey through text alone. Diagrams are referenced in the script and visually timed to appear alongside the corresponding narration. Animation Animations bring diagrams and processes to life, helping users visualize dynamic workflows. Traditionally, creating animations involves keyframing, which requires specifying how objects move frame by frame. This is time-consuming and technical. To speed up animation creation, we use AI: A simple prompt can generate the movement of objects without manually keyframing each frame. AI-generated motion can be reused across multiple animations, saving time. This approach allows motion graphics artists to focus on creative design rather than repetitive technical work. Screen recording We use screen recordings when demonstrating real product interactions by capturing UI-driven workflows directly from Cloudflare dashboards or developer tools. Best practices: Highlight relevant UI elements with callouts or overlays. Voiceover should match to guide the viewer through steps. Make sure UI elements shown are up-to-date. Blur sensitive data. Talking head We use talking head footage when a human presence adds clarity, engagement and warmth, such as: Introducing a workflow or video segment Providing context, emphasis, or commentary Reinforcing Cloudflare branding and approachability Talking head footage is especially useful when voiceover alone cannot convey tone or emphasis, helping users connect with the content. Review and quality assurance Every Cloudflare video undergoes a two-stage review process to ensure accuracy, clarity, and consistency with documentation standards. We leverage both human reviewers and AI tools to maintain high quality while enabling scalable production. Scripts are reviewed before production to ensure: Technical accuracy – Explanations of concepts, workflows, and product behavior are correct. UI and workflow accuracy – Steps described match the actual product. Terminology alignment – Language matches Cloudflare documentation and branding. Once a video is produced, it undergoes a visual review to verify: Illustration matches narration – Diagrams, animations, and callouts align with spoken content. Diagram accuracy – Architecture and conceptual diagrams correctly reflect the product. Screen recording accuracy – UI navigation, workflows, and system outputs are correct. Cloudflare uses AI to enhance quality assurance by using saved prompts that remember your review preferences and focus areas, acting as a reviewer to ensuring consistent checks across projects: Immediate turnaround, even when human reviewers are unavailable Reduces risk of errors and outdated information Advanced image recognition supports maintenance by re-checking existing videos to see if UI or information has changed Metadata and discoverability Creating videos is only part of the story. To ensure our videos are findable, useful, and accessible, we apply structured metadata and AI-assisted tools to maximize discoverability for both human users and AI systems. Before publishing, we generate rich metadata for each video: Title: Clear, descriptive, and aligned with documentation terminology Description: Summarizes the content and context of the video Chapters: Breaks the video into logical segments to improve understanding by AI Transcripts and subtitles: Videos are hosted on Cloudflare Stream, we can generate captions automatically and download caption files .vtt as transcripts. This enables: Search indexing AI retrieval Generative Engine Optimization (GEO) Why and when we use videos We believe video is a powerful tool that complements documentation to help users quickly grasp complex concepts and workflows. Not every piece of documentation should be a video and we should use it intentionally. Our goal is to apply video where it adds clarity, reduces cognitive load, and improves task completion to the original documentation. We use video when it: Explains complex workflows Demonstrates UI-driven actions Reduces friction in onboarding and first-time use Clarifies abstract or conceptual topics We do not use video for: Reference material (API fields, parameters, limits) Frequently changing UI or experimental features Content that is faster to scan in text Information users need to copy, paste, or search precisely Accessibility guidelines import { Render } from "~/components"; Create documentation that is accessible to all users, including disabled users. Following accessibility best practices ensures that everyone can access, understand, and use the Cloudflare docs effectively. These guidelines align with Web Content Accessibility Guidelines (WCAG) 2.1 Level AA standards and focus on aspects relevant to documentation. Page structure and navigation Provide informative, unique page titles Each page must have a descriptive title that clearly identifies its content and distinguishes it from other pages. Put the most specific information first in the title. Make titles concise but descriptive. Avoid generic titles like "Overview" or "Introduction" without context. Do Do not Configure SSL/TLS encryption modes SSL Settings Troubleshoot DNS resolution errors Troubleshooting WCAG reference: 2.4.2 Page Titled (Level A) Use headings to convey meaning and structure Headings provide a hierarchical structure that helps all users navigate and understand content. Screen reader users rely on headings to navigate pages efficiently. Use headings in sequential order. Do not skip levels. Make headings descriptive of the content that follows. Use only one H1 per page (the page title). Do not use headings for visual styling purposes only. :::note Our docs site framework, Astro, automatically creates headings for each page based on the page title and sidebar order. You do not need to add an initial H1 heading to the page content. ::: Do Do not Use H2 for main sections, H3 for subsections Skip from H2 to H4 Configure DNS records (describes the section) Important (vague heading) WCAG reference: 2.4.6 Headings and Labels (Level AA) Ensure logical reading order Content must be presented in a meaningful sequence that makes sense when read linearly. Structure content so it flows logically from top to bottom. Ensure code examples appear after their explanatory text. Place prerequisite information before procedural steps. WCAG reference: 1.3.2 Meaningful Sequence (Level A) Links and navigation Write descriptive link text Link text must clearly describe the destination or purpose of the link. Avoid ambiguous phrases that provide no context. Use the title of the destination page as link text when possible. Describe what the user will find when they follow the link. Avoid generic phrases like "click here", "read more", or "this page". :::note To provide accessibility across all devices, Cloudflare recommends using "select" instead of "click" when referring to a button or link action. ::: Do Do not For common issues, refer to the DNS troubleshooting guide. For common issues, click here. Learn more about configuring SSL certificates. Read more about SSL. Download the Wrangler CLI installation guide (PDF, 2MB). Click here to download. WCAG reference: 2.4.4 Link Purpose (In Context) (Level A) Avoid directional language Do not use directional or spatial language that relies on visual layout, as this creates barriers for screen reader users and does not always work across different devices. Avoid terms like "above", "below", "left", "right", "top", "bottom" unless it is necessary to describe the location of an element. Reference specific elements by name instead of location. Use section headings or labels to identify content. Do Do not In the DNS section, select your domain. On the right side of the screen, select your domain. Refer to the Prerequisites section for requirements. See the information above for requirements. Select the Add rule button. Click the button below. WCAG reference: 1.3.3 Sensory Characteristics (Level A) Images and multimedia Write meaningful alt text for images All images that convey information must have alternative text that describes the content or function of the image. Describe what the image shows and why it matters. Keep alt text concise but informative (typically under 150 characters). For complex diagrams, provide a longer description in the surrounding text. Use empty alt text (empty brackets ![]) only for purely decorative images. Do not include phrases like "image of" or "picture of" in alt text. Avoid keyword stuffing for SEO purposes. Do not repeat captions or adjacent text in the alt text. For functional images (like buttons or links), describe the action, not the appearance. Image type Alt text approach Screenshot showing a specific UI element Describe what the screenshot shows and its purpose Diagram illustrating a concept Summarize the key information conveyed Logo or icon with adjacent text Use empty alt text to avoid redundancy Decorative image Use empty alt text (empty brackets ![]) Examples: Do Do not ![Cloudflare dashboard showing the DNS records page with an A record highlighted](path/to/image.png) ![Screenshot](path/to/image.png) ![Network diagram showing traffic flow from client through Cloudflare to origin server](diagram.svg) ![Diagram of network](diagram.svg) ![](path/to/decorative-image.png) (for decorative images) ![Blue line decoration](path/to/decorative-image.png) ![Diagram of a DNS request going to a DNS resolver](dns-diagram.svg) ![DNS, DNS resolver, DNS request, how DNS works](dns-diagram.svg) (keywords) ![Submit button](submit-icon.png) ![Blue rectangular button](submit-icon.png) (describes appearance) WCAG Reference 1.1.1 Non-text Content (Level A) Additional resources: W3C Images Tutorial Provide captions and transcripts for multimedia All video and audio content must include captions and transcripts to ensure accessibility for users who are deaf or hard of hearing. Captions: Provide synchronized captions for all video content that includes audio. Transcripts: Provide text transcripts for audio-only content (such as podcasts). Audio descriptions: For videos where visual information is essential, provide audio descriptions of important visual content. Captions and transcripts must include: All spoken dialogue and narration. Speaker identification when multiple speakers are present. Important sound effects (for example, "door closes" or "alert notification"). Musical cues when relevant to understanding the content. WCAG reference: 1.2.2 Captions (Prerecorded) (Level A) 1.2.3 Audio Description or Media Alternative (Level A) Content clarity and readability Keep content clear and concise Use simple, straightforward language that is easy to understand. This benefits all users, including those with cognitive disabilities, non-native English speakers, and users with limited technical knowledge. Write in short, clear sentences (aim for 8-12 words per sentence when possible). Break content into short paragraphs (3-4 sentences maximum). Use simple words instead of complex alternatives. Avoid jargon, idioms, and colloquialisms. Use active voice and present tense. Do Do not Cloudflare protects your website from DDoS attacks. Cloudflare provides comprehensive protection mechanisms to mitigate distributed denial-of-service attack vectors. Complete these steps to configure your settings. In order to facilitate the configuration of your settings, it is necessary to complete the following steps. WCAG reference: 3.1.5 Reading Level (Level AAA) Expand acronyms and abbreviations Define all acronyms and abbreviations on first use to ensure clarity for all readers. Spell out the full term on first use, followed by the acronym in parentheses. Use the acronym consistently throughout the rest of the document. Consider providing a glossary for documents with many technical terms. Do Do not Web Content Accessibility Guidelines (WCAG) provide standards for accessible web content. WCAG provides standards for accessible web content. A Distributed Denial of Service (DDoS) attack overwhelms servers with traffic. A DDoS attack overwhelms servers with traffic. WCAG reference: 3.1.4 Abbreviations (Level AAA) Define technical terms When using technical terms that may be unfamiliar to your audience, provide clear definitions, use the GlossaryDefinition component, or link to the relevant glossary. Define terms inline when first introduced. Link to detailed explanations in a glossary or separate page. Consider your audience's technical level when determining which terms need definition. WCAG reference: 3.1.3 Unusual Words (Level AAA) Use lists for multiple items Present multiple related items as bulleted or numbered lists rather than in paragraph form. Lists are easier to scan and understand. Use numbered lists for sequential steps or ordered items. Use bulleted lists for non-sequential items. Keep list items parallel in structure. Introduce lists with a clear lead-in sentence. Instructions and user guidance Provide clear instructions Ensure that all instructions, guidance, and error messages are clear, specific, and easy to understand. Describe input requirements explicitly (for example, date formats and character limits). Provide examples when helpful. Use clear, specific error messages that explain what went wrong and how to fix it. Avoid unnecessarily technical language in user-facing messages. Do Do not Enter a valid email address (for example, user@example.com). Enter email. Password must be at least 12 characters and include one number. Invalid password. The API key format is incorrect. Ensure it is 32 characters and contains only alphanumeric characters. Error: Invalid key. WCAG reference: 3.3.2 Labels or Instructions (Level A) Do not rely on color alone in diagrams When creating Mermaid diagrams or other visual content, do not use color as the only way to convey information or distinguish elements. Use labels, patterns, or shapes in addition to color. Ensure text within diagrams has sufficient contrast. Add descriptive text near the diagram to explain key elements. Do Do not Use different shapes and labels for different node types Use only color to differentiate node types Add a legend that describes elements by name, not just by color Refer to "the green box" without additional context WCAG reference: 1.4.1 Use of Color (Level A) Tables and data presentation Use tables for tabular data only Use tables only to present data that has a logical relationship between rows and columns. Do not use tables for layout purposes. Include clear, descriptive headers for all columns and rows. Keep tables simple when possible. For complex tables, consider breaking them into multiple simpler tables. WCAG reference: 1.3.1 Info and Relationships (Level A) Code examples and technical content Make code examples accessible Ensure that code examples are accessible to screen reader users and easy to understand. Always specify the programming language for syntax highlighting. Provide context before code examples explaining what the code does. Use descriptive variable and function names in examples. Add comments to explain complex code sections. Ensure code examples follow a logical order. Testing and validation Test with assistive technology When possible, test documentation with assistive technologies to ensure accessibility. Use a screen reader to navigate the page. Test keyboard navigation (Tab, Enter, arrow keys). Verify that all interactive elements are keyboard accessible. Check that focus indicators are visible. Use automated accessibility tools Use automated tools to identify common accessibility issues, but remember that automated tools cannot catch all problems. Run automated accessibility checkers during development. Manually review flagged issues. Conduct manual testing for issues that tools cannot detect. Additional resources WCAG guidelines and documentation Web Content Accessibility Guidelines (WCAG) 2.1 How to Meet WCAG (Quick Reference) Understanding WCAG 2.1 Writing for Web Accessibility Style and grammar import { DirectoryListing } from "~/components"; This section covers how a page should read: the house voice and tone, accessibility, grammar, and formatting. Start with voice and tone, then apply the grammar and formatting rules as you write. Voice and tone import { Render } from "~/components"; Use the following writing guidelines to create product content that is clear and consistent and demonstrates Cloudflare's brand voice and product tone. The tone we use varies based on customer goals while using certain products and features. We emphasize ease-of-use within our products. Use plain language Plain language is writing that an audience can understand and act upon the first time they read it. Using plain language ensures your audience understands what you mean. Cloudflare users are a global audience whose first language might not be English. Plain language makes translation easier and documentation more accessible. Consider the following tips for using plain language in your writing: Put important messages in the beginning. Avoid obscure words. Use simple sentences. One sentence should be one idea. Avoid abbreviations. Be consistent. For more information about plain language, refer to the Plain Language Guide Series. Prioritize the customer Center your content around customer objectives rather than Cloudflare’s business objectives. Write with the objective first, then the action. Provide information as needed Keep the information given pertinent to the particular point in the user’s journey. Make sure to define or give more context for any metrics provided. Do not list performance statistics in feature descriptions. Communicate confidently Use a confident and clear tone that prevents customer doubt. Guide from a place of expertise without talking down to the audience. Always show the primary answer Introduce complexity progressively When introducing technical concepts, start with the basics and gradually build up to more advanced topics. Explain the "why" before the "how". Avoid jargon and technical language Communicate concepts without using jargon. Replace it if possible. Define acronyms and technical terms. Refer to the table for examples of how to translate jargon into plain language: Jargon Plain language Do a GET. Submit a GET request. Use the out-of-the-box settings. Use the default settings. You can deploy Cloudflare Enterprise services on-prem. You can deploy Cloudflare Enterprise services on-premises. Perform an execution of the process steps with a core focus of ensuring that the deployments do not conflict. Make sure that no deployments conflict with one another. Consider the following to help you avoid jargon in your writing: Consider your audience's level of knowledge. Consider if the user needs to know the term to complete a task or understand the documentation. Use active voice and present tense Active voice is more concise and direct than passive voice and should be used whenever possible. Make the message clear and comprehensible to anyone using Cloudflare's products. Choose clarity over concise copy. Do Don't Rationale Cloudflare Load Balancing automatically reduces latency by directing visitors to infrastructure closest to them. Latency is automatically reduced by Cloudflare Load Balancing. Visitors are directed to infrastructure closest to them. Writing this sentence in the active voice shifts the focus from the pain point (latency) to the solution (Cloudflare Load Balancing). Now, paired with the HTML Rewriter API, you can perform DOM transformations on top of your static HTML. Now, paired with the HTML Rewriter API, DOM transformations can be performed on top of your static HTML. Writing this sentence in the active voice shifts the focus from the product to the customer. Use present tense verbs. Avoid past tense whenever possible, as it can quickly make content feel outdated or irrelevant. Future tense should only be applied to actions that have not happened yet. Do Don't Rationale FindLaw uses Cloudflare to accelerate and secure thousands of customer sites. FindLaw used Cloudflare to accelerate and secure thousands of customer sites. FindLaw is a current customer who still benefits from the performance and security Cloudflare provides, so we should refer to them in the present tense. Be solutions-oriented Focus on solving problems. Anticipate customer problems to write with solutions in mind and embedded in the interface. Write accessible documentation Create product content that is accessible to people with disabilities. Accessibility ensures that all users can access, understand, and use Cloudflare documentation effectively. Key accessibility practices include: Provide informative, unique page titles. Use headings to convey meaning and structure. Make the link text meaningful. Write meaningful text alternatives (alt text) for images. Create transcripts and captions for multimedia. Provide clear instructions. Keep content clear and concise. For comprehensive accessibility guidelines aligned with WCAG 2.1 standards, refer to the Accessibility guidelines page. Write clear and concise sentences Use simple language and formatting, as appropriate for the context. Respect our users’ time. Keep sentences between 8 to 12 words. Write in short, clear sentences and paragraphs. Avoid using unnecessarily complex words and phrases. Expand acronyms on the first use. For example, Web Content Accessibility Guidelines (WCAG). Consider providing a glossary for terms readers may not know. Use list formatting as appropriate. Consider using images, illustrations, video, and symbols to help clarify meaning or when a written description is unintuitive. Write effective page descriptions Every page with a pcx_content_type must include a description in its frontmatter. The description populates the tag, which search engines and AI systems use to decide whether to surface or cite a page. Apply the same plain language principles to descriptions as you do to body content: Write 1-2 self-contained sentences. Name the product or feature. State what the page helps the reader do or understand. Write so the description works as a standalone answer snippet when extracted from the page. Do not start with generic openers: Do not use Why "This page describes..." Wastes space on framing instead of information. "Learn more about..." Does not state what the reader will accomplish. "This document explains..." Adds no information beyond the title. For detailed guidance and examples, refer to Writing a description. Use consistent terminology Apply the same unambiguous word or term consistently throughout a document. Clarify gerunds and participles Participles are verbs that end in -ed or -ing and act as modifiers. Gerunds are verbs that end in -ing and act as nouns. Both types of words are useful and acceptable, but they can cause confusion if they are misplaced in a sentence. For example, the word meeting can be a gerund or a participle (or even a noun) depending on its placement in a sentence. When you use gerunds and participles, ensure that the meaning is clear. Do Don't A job can include metadata that schedules the program to run at a specified date and time. A job can include scheduling metadata that enables the program to run at a specified date and time. Public Cloud is infrastructure that consists of shared resources, deployed on a self-service basis over the Internet. Public Cloud is infrastructure consisting of shared resources, deployed on a self-service basis over the Internet. Test the certificate by using a browser to connect to your server. Test the certificate using a browser to connect to your server. When you use a load balancer with a public-facing IP address, this address becomes the IP address of your website. When using a load balancer with a public-facing IP address, this address becomes the IP address of your website. The last example illustrates a dangling modifier. In the "Don't" example, using does not have a subject, so the implied subject is address, which is incorrect. If the implied subject is not correct, you must revise the sentence to provide a subject for the modifying phrase. The titles of tutorial or high-level process articles or topics typically start with a gerund. Titles have less context than sentences, so you must be especially careful to ensure that the meaning is clear. Do Don't Options for editing or Editing of options Editing options Billing for services Billing services Changing the DNS settings on Windows Changing DNS settings on Windows Changing a password Changing passwords Write for internationalization (I18n) Cloudflare has a global customer base. To be inclusive of all our customers and make the process of internationalization smoother, consider certain guidelines for content that is meant to be translated. In addition to all our general product writing guidelines, use the following guidelines to ensure what you write is localization-friendly. Write clearly: An unclear message is difficult to translate, if not impossible. If it is not clear in English, it will not be clear in any other language. Avoid cultural references: Specific cultural references only make sense to the locale you are writing from or a small subset of our customers, so do not use them in product or documentation. Do not use contractions: Even with space constraints, do not use contractions. They are specific to English and difficult to translate. Give definitions and contextual information: Never use a technical term or acronym without defining it. For terms that are not translatable, information and context matter. Write inclusive documentation Write documentation with inclusivity and diversity in mind. Here are some general guidelines and examples that illustrate some best practices to follow. The language we use to describe and discuss our products, features, and processes is important. Whether we are writing a blog post, leading a webinar, or developing a campaign, our goal is always to create inclusive content that speaks to our global, diverse audience. We do not use racist, gendered, or ableist terminology. In addition to the guidelines outlined below, we have identified and replaced several industry-related terms which can be offensive or painful to people from certain backgrounds, cultures, and/or creeds. Do not use terms that are rooted in racism. We do not use terms that describe good outcomes and actions as "white" and bad actions or outcomes as "black" (such as whitehat/blackhat hacker) nor do we use common industry terms that stem from language used to describe slavery (such as master/slave). Do Don't Rationale Many search engines will block your site if you are hosting malicious content, which only compounds the issue for site owners that do not know that they have been compromised. Many search engines will blacklist your site if you are hosting malicious content, which only compounds the issue for site owners that do not know that they have been compromised. Since we do not want to use "black" to refer to a negative action here, we replace the term "blacklist" with a neutral, descriptive term that clearly explains the action that is being performed (in this case, "block"). Replace gendered terms with non-gendered terms. Gendered language may be used when referring to specific people with known pronouns. It is unnecessary when discussing products and technical processes — for instance, referring to a hypothetical attacker as "he" or a piece of hardware as "she." Do Don't Rationale One type of attack that could trigger a browser warning is a so-called on-path attack. In this attack, an attacker places themselves in between a visitor and a website, impersonating both. One type of attack that could trigger a browser warning is a so-called man-in-the-middle (MitM) attack. In this attack, an attacker places himself in between a visitor and a website, impersonating both. Because a "man-in-the-middle attack" is a term, not a reference to a specific attack carried out by a man, we opt for the term "on-path attack" and attach gender-neutral they/them pronouns when describing the attacker. Avoid ableist terms and metaphors. This does not just apply to industry terms, but to descriptors like "crazy" and "insane," which reinforce negative, ableist stereotypes. Do Don't Rationale As Workers use cases grow in complexity, the need to validate your code also grows. As Workers use cases grow in complexity, the need to sanity check your code also grows. We avoid metaphorical terms that reference mental health, like "sanity check," and replace them with words that more accurately describe the process taking place (in this case, "validate", though "smoke test" is also an approved replacement). Define new and unfamiliar terms When writing or editing, recognize terms that might be unfamiliar to some or all of the audience. When you spot a such a term, take one of the following tactics: If the term already exists, link to a good existing explanation. If your document is introducing the term, define the term. Use short, familiar words and phrases Words that are conversational, save space, and are easier to scan are often easier to read for non-native English speakers. Long words or phrases may be necessary to convey a particular meaning, but should be used sparingly. Follow web standards To effectively communicate online, you need to follow web standards, design for reading, and repurpose print materials for the web. For more information about web standards, refer to the Plain Language Guide Series. Include use cases Include short examples of real life use cases. Back up the main point being discussed with these examples. Be purposeful and deliberate when adding these examples - every example must serve a clear purpose and add value to the reader. URLs and domain names When referring to a URL in text, do not use http:// or www with a Cloudflare web address. Use www only when referring to URLs outside of Cloudflare. For example, use cloudflare.com when referring to cloudflare.com and www.example.com when referring to www.example.com. Code block guidelines To create a code block: Use triple-grave characters ( ```) as a fence, and enter a language name after the first ``` fence Indent lines by four spaces or one tab Learn about conventions for code blocks Learn about code block special formatting and functionality Here is an example of a JSON code block: ```json { "firstName": "John", "lastName": "Smith", "age": 25 } ``` The rendered output looks like this: { "firstName": "John", "lastName": "Smith", "age": 25 } Add output To add the output of your code block, create a second code block below the first and add the output property to the opening code fence, like this: npx wrangler vectorize create tutorial-index --dimensions=3 --metric=cosine ✅ Successfully created index 'tutorial-index' [[vectorize]] binding = "VECTORIZE_INDEX" # available in your Worker on env.VECTORIZE_INDEX index_name = "tutorial-index" ```sh npx wrangler vectorize create tutorial-index --dimensions=3 --metric=cosine ``` ```txt output ✅ Successfully created index 'tutorial-index' [[vectorize]] binding = "VECTORIZE_INDEX" # available in your Worker on env.VECTORIZE_INDEX index_name = "tutorial-index" ``` Languages To define the language of your code block, enter the name of the language after the first ``` fence. Language names must be lowercase. For example, use javascript, not JavaScript. Use txt (aliases: text, plaintext) when there is no appropriate syntax language. Terminal commands Use the sh or bash language for commands executed in the Linux/macOS terminal, including: One-line commands Commands that span multiple lines (usually each line ends with a \) Commands for specific shells (for example, a command specifically for the zsh shell) Use the powershell language for Windows PowerShell commands. When rendered, these blocks will have a PowerShell title. Use the txt language for Windows console commands. The Copy to clipboard button, available in the top-right corner of each code block, will copy the entire content of the code block, including any command output included in the block. Do not include a prefix ( $, %, PS>, C:\>, or similar) before a command so that the user can run the command immediately after copying and pasting without having to remove the prefix. Similarly, do not write the folder where the command is being executed unless it is an essential part of the explanation. JSON Use json for JSON code blocks or JSON fragments. Multi-line curl commands with a JSON body should use the sh or bash syntax highlighting, as stated in Terminal commands. :::note JSON fragments may appear with a red background in GitHub because they are not valid JSON. Make it clear in the documentation that it is a fragment and not an entire piece of valid JSON content. ::: Add special formatting You can add special formatting to code blocks, such as collapsed sections, line numbers, and highlighting. Here is a showcase of some of the functionality. You can find more options at Expressive Code, a project by Astro. ```powershell title="Write string example" Write-Output "This one has a title" ``` ```js collapse={3-5} // Collapsing const foo = { 1: 1, 2: 2, 3: 3, }; ``` ```js showLineNumbers // Line numbers const foo = "bar"; const bar = "baz"; ``` ```js wrap // Example with wrap function getLongString() { return "This is a very long string that will most probably not fit into the available space unless the container is extremely wide"; } ``` ```js "return true;" ins="inserted" del="deleted" function demo() { console.log("These are inserted and deleted marker types"); // The return statement uses the default marker type return true; } ``` ```diff lang="js" function thisIsJavaScript() { // This entire block gets highlighted as JavaScript, // and we can still add diff markers to it! - console.log('Old code to be removed') + console.log('New and shiny code!') } ``` :::caution Do not use the $ sign in your code blocks before a command. ::: Workers Playground If you add the playground option to the opening code fence for a Worker example, it will add a "Run Worker in Playground" link that will take the user to the Worker's playground. Live demo export default { fetch() { return new Response("Test!"); }, }; How to use ```js playground export default { fetch() { return new Response("Test!"); }, }; ``` GraphQL API Explorer Add graphql-api-explorer to the opening code fence to create a graphql code block with a Run in GraphQL API Explorer button that leads to GraphQL API Explorer. :::note This button only works if the person selecting it is logged in or has an API token saved. ::: ```graphql graphql-api-explorer title="A GraphQL query" query ASingleDatasetExample($zoneTag: string, $start: Time, $end: Time) { viewer { zones(filter: { zoneTag: $zoneTag }) { firewallEventsAdaptive( filter: { datetime_gt: $start, datetime_lt: $end } limit: 2 orderBy: [datetime_DESC] ) { action datetime host: clientRequestHTTPHost } } } } ``` Variables In the GraphQL API Explorer, the Variables section is automatically filled based on the names and types of the variables defined in your query: Variables that include start and are of type Time are set to six hours before the current time Variables that include end and are of type Time are set to the current time Variables that include start and are of type Date are set to 24 hours before the current date Variables that include end and are of type Date are set to the current date Variables that include zoneTag and are of type string are set to "ZONE_ID" Variables that include accountTag and are of type string are set to "ACCOUNT_ID" Variables that include id and are of type string are set to "REPLACE_WITH_ID" Variables that include limit and are of type int are set to 100 Any other variable with a type of string is set to "REPLACE_WITH_STRING" You can also add custom variables by setting their values as a JSON string in the graphql-api-explorer metadata. The custom variables will be merged with the automatically populated variables. In the following example, the custom value is custom-variable: ```graphql graphql-api-explorer='{"uID": "custom-variable"}' title="A GraphQL query" query GraphqlExample($zoneTag: string, $start: Time, $end: Time) { viewer { zones(filter: { zoneTag: $zoneTag }) { ... } } } ``` So, the Variables would look something like this: {"zoneTag":"ZONE_ID", "start":"2025-09-11T14:00:00Z", "end":"2025-09-11T20:00:00Z", "uId":"custom-variable"} Code conventions and format Use the conventions described below throughout Cloudflare product content. Learn about code block formatting guidelines Angle brackets ( < and > ) Use angle brackets to denote placeholders for variables you want the user to enter (except in API URLs and API authentication headers, where you should use the $ZONE_ID / $CLOUDFLARE_API_TOKEN format). Placeholder text should have all capital letters and use underscores ( _) to separate words. Examples: { "description": "" } https://.cloudflare.com Angle brackets that contain numbers separated by an ellipsis represent a range of values associated with a bit or single name - for example, AO <0...3>. Square brackets ( [ and ] ) Square brackets enclose optional items. Example: Specify a subsearch that starts with this search command: tag=dns query [search tag=malware]. Curly braces ( { and } ) As a general rule, do not use curly braces for URL or variable placeholders. Instead, refer to angle brackets. Curly braces are acceptable around parameter names when referring to a specific API schema path (for example, /api/v4/{account_id}). However, in API examples ( curl blocks or APIRequest blocks) use shell variables instead (for example, $ACCOUNT_ID). The APIRequest component handles this automatically for variables in the API operation's URL path. For more information, refer to Guidelines for cURL commands. > The > symbol leads you through nested menu items and dialog box options to a final action. The sequence Options > Settings > General directs you to pull down the Options menu, select the Settings item, and select General from the last dialog box. Do not use bold formatting for the > symbol. Tip icon This icon denotes a tip, which alerts you to advisory information. Note icon This icon denotes a note, which alerts you to important information. Info icon This icon denotes info, which alerts you to important information. Notice icon This icon denotes a notice, which alerts you to take precautions to avoid data loss, loss of signal integrity, or degradation of performance. Caution icon This icon denotes a caution, which advises you to take precautions to avoid injury. Blue text Text in this color indicates a link. Bold Use bold when referring to a clickable action or to highlight a title or name in the UI. Bold text denotes items that you must select or click in the software, identifiers in the UI, or parameter names. Do not use bold for programs. In nested menus, use bold for the word not the symbol. Example: Dashboard > This > That Italics Use italics when referring to an option that customers can select from, like in dropdown menus. Do not use italics when referring to the state of a toggle - for example, enabled/disabled should not be italicized. Monospace `text in between backticks` Text in this font denotes text or characters that you should enter from the keyboard, sections of code, programming examples, and syntax examples. This font is also used for the proper names of drives, paths, directories, programs, subprograms, devices, functions, operations, variables, files, API commands, and extensions. Examples of elements we monospace Element Example IP addresses and ranges Change your system + DNS servers to use 127.0.1.1. Port numbers Requests are redirected through the HTTP service (port 80). API commands The endpoint supports GET for JSON format. Terminal commands Run the command wrangler login. Attribute names and values type, name Class names button-primary Command-line utility names wrangler, npm, node, cloudflared Data types ( string, number, int64) Defined (constant) values for an element or attribute DNS record types The bot will default to looking for AAAA records. However, you may use regular formatting (for example, AAAA) if there are multiple inline occurrences or if the text is a hyperlink. Enum (enumerator) names (depending on language) type ContentTypeMapElem Environment variable names Element names, including angle brackets (XML and HTML).
,
, , Filenames, filename extensions (if used), and paths wrangler.toml, wrangler.jsonc Folders and directories ~/Downloads/Cloudflare_CA.crt HTTP verbs POST, GET, HEAD, PUT, DELETE HTTP status codes 400, 200, 500 However, error ranges using x placeholders should not be monospaced: 5xx, 1xxxx. HTTP content-type values text/html, application/javascript; charset=utf-8 HTTP header names Content-Length URLs that are used as input or output in commands and code VERSION-dot-SERVICE-dot-PROJECT_ID.REGION_ID.r.appspot.com IAM role names roles/storage.admin Language keywords in, await Method and function names handleRequest Namespace aliases numpy Placeholder variables Query parameter names and values /api/v4/{account_id} Text input "Hello Worker" Dates and times To account for internationalization and inclusivity of all locales, use the ISO-8601 (YYYY-MM-DD hh:mm:ss) standard when writing dates and times as much as possible. In general, documentation should strive to represent universal truth, not something time-bound. This is why semgrep may flag uses of explicit dates or month names or years because often become out-of-date and not be revised later. Blogs Since our readership is international, keep date formats international. When mentioning dates in text, spell them out: On Tuesday, May 19, attackers targeted the company's servers. On February 11th, 2010, the company went public. For graphs, charts, and other visual assets use the ISO-8601 (YYYY-MM-DD hh:mm:ss) standard. Example values As described in RFC 2606 and RFC 6761, a number of domains such as example.com and example.org are maintained for documentation purposes. Sometimes you also need to differentiate between a customer domain and your own application domain, so Cloudflare has also registered some domains for you to use. Examples: example.com example.org myappexample.com mycustomerexample.com IANA also maintains more example domains in their domain names documentation. IPv4 ranges According to the Internet Engineering Task Force (IETF), there are specific IPv4 ranges used for documentation: Examples: 192.0.2.0/24 198.51.100.0/24 203.0.113.0/24 These IP addresses are reserved and will not take anyone to live origins. Autonomous System Numbers (ASNs) According to the Internet Assigned Numbers Authority (IANA), there are specific ASN ranges reserved for documentation: 64496-64511 (16-bit ASN range) 65536-65551 (32-bit ASN range) External references When referencing external resources, ensure that you are linking to a trustworthy source that is recognized as an authority. For general websites, consider the following recommendations about the link text: Use the website name if you are linking to the home page. Use the page name if you are linking to a specific page. Authoritative sources for documents such as RFCs can have their own specific format for references, such as the RFC number. :::note When linking to a Cloudflare blog post, sometimes we use only "blog post" for the link text. ::: Referencing RFCs A Request for Comments (RFC) document is a formal document produced by different entities such as the Internet Engineering Task Force (IETF), covering many aspects of computer networking. RFCs describe the Internet's technical foundations, such as addressing, routing, and transport technologies. Use the following formatting when referencing an RFC: RFC (RFC, space, number up to four digits) Example: CAA is a new DNS resource record type defined in RFC 6844. Links When linking to an RFC (or RFC section), consider using a link to the following website, which is the authoritative source according to IETF: https://www.rfc-editor.org To get the link: Go to RFC Editor and search for the RFC number. Select HTML to open the HTML version. If available, do not use HTML with inline errata as this version should not be used as reference. (Optional) Go to a specific section, if necessary. Use the current URL as the link target in Developer Documentation. URL example: https://www.rfc-editor.org/rfc/rfc6844.html File types and extensions You can refer both to file types and file extensions in documentation: File types: Accepted file formats are JSON and YAML. File extensions: Upload the .txt file to the dashboard. When referring to a specific file type, always use regular text formatting, write the file type in uppercase, and avoid the initial dot (you are referring to the file type, not the file extension). When referring to a specific extension, always monospace the file, include a dot, write the extension in lowercase, and always specify a noun after mentioning a file extension (for example: "file" or "file extension"). Do not leave the extension hanging. Additional examples: The accepted file formats are YAML (files with a .yml or .yaml file extension) and JSON (files with a .json file extension). Additionally, this plist can be wrapped in a .mobileconfig file. If you would like to test how this feature works, here is a sample .csv file. Concatenate the string to a text-based .pem file. Footnotes Use footnotes to add details or context about something without distracting from the main content. We recommend using hover-activated footnotes, but you can also use plain text. Hover-activated footnotes To add hover-activated footnotes, use the following syntax: This is a sentence with a footnote.[^1] [^1]: A footnote adds details or context. With this type of footnote, you can add the numbers to the MDX file in any order and they will still display in numerical order on the page. The hover ability of this type of footnote is powered by tippy.js. :::caution Do not use this syntax inside blocks or in partials included inside blocks. It generates a ## Footnotes heading inside each tab panel, which repeats across tabs and breaks agent-readable documentation. Use plain text footnotes or inline the text instead. ::: Plain text footnotes To add plain text footnotes, use the syntax in this example: This is a sentence with a footnote.1 1 A footnote adds details or context. With this type of footnote, you can add the footnote note anywhere on the page. We recommend adding it to the bottom of the section or table where the footnote is referenced or to the bottom of the page. Formatting import { DirectoryListing } from "~/components" Keyboard keys Use select instead of click when directing users to choose or select objects, commands, or options. Use press only when referring to pressing keys on a keyboard. Formatting keyboard shortcuts When telling readers what keyboard shortcuts to use to achieve a result: Place the keyboard shortcut in between backticks (monospace formatting) Use uppercase letters with the abbreviated version of the key ( CTRL instead of CONTROL, CMD instead of COMMANDfor example) Wrap the complete keyboard shortcut in between backticks, including the plus sign: Do: `CTRL + C` Don't: `CTRL` + `C` Do not use the old component Notes and other notation types When adding a note to a page, always use this special note formatting. There are three types of formatted notes: note, caution, and tip. Here is some additional information about notes: The color of the note depends on the type of note: note is blue, caution is yellow, and tip is purple. For every note type, the header text is optional. All note types can contain text and additional formatting like lists, code blocks, and images. To learn how notes fit into our content strategy, refer to Notes/tips/warnings. Note Use Note for small additions or when you need to provide extra context that is not essential to the main content. If you do not provide a header, this aside will default to Note. :::note[Header] Hello, world! ::: :::note[Header] Hello, world! ::: Caution/Warning Use Caution to highlight actions that could cause issues for a user. If you do not provide a header, this aside will default to Warning. :::caution[Feature conflict] If you use feature A and feature B together, your configuration will not work. ::: :::caution[Feature conflict] If you use feature A and feature B together, your configuration will not work. ::: Tip Use Tip to share best practices or opinionated use cases that do not fit into the main documentation. If you do not provide a header, this aside will default to Tip. :::tip[Best practice] Cloudflare recommends you use [1.1.1.1](/1.1.1.1/) as your DNS resolver. ::: :::tip[Best practice] Cloudflare recommends you use 1.1.1.1 as your DNS resolver. ::: Numbers and units of measurement Be consistent in your use of numbers. Use numerals for numbers. When you write about numbers used in examples or UI, duplicate them exactly as they appear in the UI. In all other content, follow the guidelines below. In body text, spell out whole numbers from zero through nine. Example: We have added three more servers. For numbers greater than or equal to 10, use digits. Example: The message is 32 bytes long, [...] For analytics, display metrics with numerals. Use commas for numbers with more than 3 digits (no spaces). Note the differences in numerical punctuation for translation. 300 1,000 7,465 Using k to indicate thousands Do not put a space between the number and k. Add a noun to indicate what the number measures, and to make clear that you are not using k as an abbreviation for kilobytes. Example: On this plan, you are limited to 55k download operations and 20k upload operations per day. Units of measurement Units of measurement can occur in two different contexts. As nouns The storage provider landscape has become highly competitive with many providers capable of providing petabyte (and exabyte) scale content storage at extremely low cost-per-gigabyte. As modifiers of numbers Many CPU architectures either do not allow execution of the machine code, which is unaligned in memory (4 KB for x86 systems) In general, only abbreviate units of measurements when they modify specific quantities/numbers. When you need to abbreviate them: ✅ ❌ Rationale 10 m 10m Always include a space between the number and the unit 10 cm 10 cms Unit symbols should unaltered in the plural. Always include a space between a numerical value and the corresponding unit of measurement. Although both formats are widely used, the metric system standardized the use of a space before a unit of measurement and should be used as a guideline to keep content consistent and clear. ✅ ❌ Rationale 128 GB 128 gb, 128gb, 128GB Units of measurement should always be capitalized and spaced out from their corresponding numerical values. This network has a capacity of over 30 Tbps. This network has a capacity of over 30Tbps. Adding a space between ‘30’ and ‘Tbps’ makes this sentence easier to read. Physical distance Measurement Example inches Although Harvey's category was quickly downgraded, the storm lingered around for days, bringing 50 inches of rain to the greater Houston area. feet, meters At 2625 meters (8612 feet) above sea level, Bogotá (Colombia) is one of the four highest capital cities in the world. Now, it is also home to Cloudflare's 149th data center. miles Despite having a unique place on the map of the United States, and its significant distance from other cities (900 miles to Dallas; 1,000 miles to Chicago, 1,000 miles to Los Angeles), Denver has not always been a major point of regional interconnection. Digital storage Measurement Example Bit (b) Typical RSA key sizes are 1,024 or 2,048 or 4,096 bits. Byte (B) Here is a small program that creates a lot of garbage. Once a second it asks for a byte array of between 5,000,000 and 10,000,000 bytes. Kilobyte (KB) Internally, ACME never stores objects that are larger than a configured size (32 kilobytes, by default). Many CPU architectures either do not allow execution of the machine code, which is unaligned in memory (4 KB for x86 systems). Megabyte (MB) To do that, we extracted one batch of records from ACME and ran some benchmarks on it. All batches are around 1 MB uncompressed, 600 records in each on average. Additionally, we had a two megabyte maximum size for values. We have increased the limit for values to ten megabytes. Gigabyte (GB) Pro plans will be able to use up to 5 gigabytes for free each month. Biz plans can go up to 10 GB for free. Terabyte (TB) Fortunately, I came across Cloudflare. In the month of October alone, CloudFlare has saved us about 1.54 TB. That is 500 terabytes, 500 million megabytes, or approximately the equivalent data contained in 1 billion books. Petabyte (PB) PB Exabyte (EB) EB Zettabyte (ZB) ZB Yottabyte (YB) YB Product name and pluralization Product names should follow a noun-verb agreement such that the verb is singular. Examples: Cloudflare Pages enables/allows. Cloudflare Workers executes/propagates. UI elements UI elements are the interactive parts of a product. They are used to build the software's interface. When describing UI elements in writing, we focus on what users need to do without focusing on the UI. To clarify instructions for complex interfaces, you may need to identify elements by name. UI element Usage Example Button Select Add a Site. Checkboxes and radio buttons Turn Set as Default DNS Location on. Commands Go to File, then select Delete. Error message If you receive the error message Invalid IP, start the process from the beginning. Menu In the menu, go to your account > Websites. Tab Go to Action. Toggle Turn AV inspection on. Containers (windows, screens, pages, sections, and cards) Refer to your site's traffic statistics for more information. Interactions When describing navigation elements, such as menus, use go to instead of navigate. When describing elements you can activate, such as checkboxes and toggles, use turn on/ turn off instead of enable/ disable. For information on physical inputs, such as mouse buttons, refer to Keyboard keys. Symbols in UI element names Icons or non-alphabetic characters The names or labels on buttons and other UI elements may include icons or symbols. For example, a button named + Add element includes a plus sign. When writing these names or labels in procedures, do not include symbols. They are usually redundant and can be removed safely. If an element has no text other than the symbol (for example, just +), you can keep the symbol in the instructions. This especially applies to instructions in interfaces for third-party products. Ellipses An ellipsis is a set of three dots ( ...) that might be used as a variable or wildcard. For example, a Save As... menu item might display a dialog box where you can save a file in different places. If you refer to a menu item or button that has an ellipsis, do not include the ellipsis. In text, ellipses can be distracting. Structure import { DirectoryListing } from "~/components" Links import { Render } from "~/components"; A link is a reference to another page, part of a page, or external resource. Hyperlinks are useful, but if overdone, they can distract the reader. Follow these guidelines for link text and placement. Types of links Create links Use the path to the product when creating a link. Do: This is a link for Cloudflare WAN's [Get started](/cloudflare-wan/get-started/) Don't: This is a link for Cloudflare WAN's [Get started](https://developers.cloudflare.com/cloudflare-wan/get-started/) Also not supported: Relative links: A link to [`DurableObjectNamespace::get`](./namespace) Using the file extension in links: This is a link for Cloudflare WAN's [Get started](/cloudflare-wan/get-started.mdx/) Standard text As much as possible, use text that follows one of these patterns: For more information, refer to [](LINK). To , refer to [](LINK). Do not use the following constructions: Learn more about... To read more.... For more information, refer the [Merge requests](LINK) page. For more information, refer the [Merge requests](LINK) documentation. Descriptive link text The more descriptive your link text, the easier it is for people to navigate your site and for Google to understand what you are linking to. Practically, this means you should avoid link text like here, this page, or read more. For example, instead of: For more information, refer to [this page](LINK). For more information, go [here](LINK). Use: For more information, refer to [set up Cloudflare](LINK). Follow these additional guidelines for inline paragraph links: Use the actual title of the target page, or an abbreviated version of that title. This helps readers confirm they reached the page they intended to visit. Use unique link text. Speech recognition software does not handle duplicated link text well. Use in-paragraph links only when they are internal to Cloudflare's websites and the material relates directly to what is being described. Consider whether the linked content helps the reader make a decision or accomplish something before continuing to read. Avoid directional language. Dashboard link text When directing users to the Cloudflare dashboard, use the following convention: 1. Log in to the [Cloudflare dashboard](https://dash.cloudflare.com/login) and select your account and domain. 2. Go to **DNS** > **Records**. Related resources Use a Related resources section at the end of your document for: Internal links that loosely relate to the topic or offer a chance for deeper learning All external links (not residing in Cloudflare's websites) Internal and external links that represent the next logical steps to follow External links placed in-paragraph are strongly discouraged because Cloudflare has no control over them. For example, if a link no longer resolves, our content feels less reliable. By shifting all external links to the end of the document, the impact of a broken link is less dramatic. Cross-linking requirements Cross-links between related pages create a navigable knowledge graph. When an AI system encounters a concept page, it can follow links to find step-by-step instructions, troubleshooting guidance, or reference data and cite the most relevant page for a user's query. Search engines use the same link structure to understand topic relationships. Every page with a pcx_content_type should include links to related pages in its Related resources section. Use the following table to determine which content types to link to from each page. Content type Must link to Concept Related how-to or get-started page; related reference page How-to Prerequisite concept page; relevant configuration page; troubleshooting page Get started Next-level how-to pages; product overview page Troubleshooting Related how-to page; relevant configuration page Configuration Parent how-to or get-started page; relevant concept page Reference Related concept page; how-to pages that use the reference Tutorial Related product overview; prerequisite get-started page Links should be bidirectional. If a concept page links to a how-to, the how-to should link back to the concept page. This ensures that users (and AI systems) can traverse between pages in either direction. Example A concept page about DNS records should link to related how-to, troubleshooting, and reference pages: ## Related resources - To create or modify DNS records, refer to [Manage DNS records](/dns/manage-dns-records/how-to/create-dns-records/). - For common DNS issues, refer to [Troubleshoot DNS records](/dns/troubleshooting/). - For a complete list of supported record types, refer to [DNS record types](/dns/manage-dns-records/reference/dns-record-types/). The corresponding how-to page should link back: ## Related resources - To learn how DNS records work, refer to [DNS records](/dns/manage-dns-records/). - For record type details, refer to [DNS record types](/dns/manage-dns-records/reference/dns-record-types/). - For common DNS issues, refer to [Troubleshoot DNS records](/dns/troubleshooting/). When links do not exist Not every content type will have a matching page for every row in the table. Link to what exists. If a related page does not exist yet, do not create a placeholder link. Instead, consider whether the missing page represents a gap in the doc set that should be addressed. Links for instructions in documentation Place links for example requests and API calls in code blocks. Use placeholders in links with account- or user-specific information, and explain what to replace the referential text with. For example, for the link " https://api.cloudflare.com/client/v4/accounts/a0b1c2d3/rulesets" use " https://api.cloudflare.com/client/v4/accounts//rulesets" and add text to say "replace with your Account ID" or similar. Refer to angle brackets in Code conventions and formatting. Maintenance For more details on how we handle link maintenance, refer to Link maintenance. Lists There are three types of lists: Bulleted lists for unordered items Numbered lists for ordered items Embedded lists for items within a sentence Here are some tips when creating lists: Keep list items parallel Start numbered lists with a command (imperative verb) Consistently punctuate by using appropriate sentence + punctuation within the list (periods for full sentences, etc.) Bullet points Bullet points help the reader's eye focus on a list of important elements. However, as with any other aspect of writing, they should be used mindfully. Below is a list of when you should and should not resort to bullet points. ❌ Do not use bullet points ✅ Use bullet points To outline processes (prefer numbered lists) To list facts To explain your reasoning (it is a blog post, not a list of system requirements) To list data - To list options Bulleted lists Instructions should be numbered steps and not bullet points. See steps/tasks/procedures for additional information. Do not punctuate bullet points unless each item is a full sentence. If bullet point items are followed by a description, use a colon after the heading and capitalize the description. For example, Item 1: Description 1 Item 2: Description 2 For bullet points, try to stick to the "six-pack" rule: no more than six bullets, each made up of six words or less. Refer to The best way to use bullet points for additional guidance. Bulleted list checklist When you find yourself creating a list of bullet points, go through this checklist: Do all bullet points belong together? Check that all the elements in the list are logically connected. Do I have more three or more bullet points, but less than six? Readers get lost when reading long lists; at the same time, if you have less than three elements to list, is it necessary to use bullet points? Are all bullet points shorter than three lines of text? Bullet points should not be used as section headers. If you have excessively long bullet points, consider breaking up the list into several subsections. Is punctuation consistent? End all elements of a bulleted list with a period if each element is a full sentence; do not add any punctuation if you are just listing nouns or parameters. Do all bullet points start with the most important word we want the reader to remember? Make sure the "head" of your bullet point is not hiding after a long circumlocution. Do all bullet points start with the same part of speech? If your bullet points start with verbs, make sure all verbs are in the same mood/tense. Paragraphs and line breaks To start a new paragraph, leave an empty line (with no spaces) before adding the new paragraph content. This sentence is the first one in this paragraph. This second sentence also belongs to the first paragraph. This is the first sentence of the second paragraph. Line breaks in Markdown Avoid line breaks when possible. Considering creating a separate paragraph, even inside numbered lists. If you need to add a line break, use the
HTML element. Example inside a table: | Feature | Enabled | |----------------------------------|---------| | Feature name
Additional info | Yes | This is how the table looks: Feature Enabled Feature name Additional info Yes :::caution Do not use two spaces at the end of a sentence to create a forced line break. Although this Markdown syntax is supported, it is not immediately visible and can easily miss these line breaks during peer reviews. ::: Sentence structure Fifteen words or fewer is a good rule of thumb for readability. You can use the Hemingway App to check length and reading level. Break up longer or difficult-to-read sentences into shorter chunks. In the Cloudflare dashboard, keep only what is necessary to convey the message. For example, complete sentences and certain words ("the," for example) are not always necessary. Spaces between sentences One space between sentences. Tables import { Render } from "~/components"; Using tables to simplify content and data provides a comprehensive way to arrange design, structure, outlines, pattern, or order. It is a great tool for comparisons, breakdowns, lists, functions, and descriptions. :::caution Try limit tables to four columns where possible, otherwise, mobile users will have a hard time consuming tabular information. ::: Here are some tips when creating tables: Label column headers. Label row headers if appropriate. Avoid merged cells. Merged cells break screen reader navigation and make content harder for AI systems to parse. Avoid too much text. Limit each cell to one sentence of content. Aim for parallelism within the column. Keep tables as simple and as small as possible. Sort rows in a logical order. If no logical order exists, use alphabetical order. Introductory sentences When referring to a table, use a phrase like "the following table" or "the preceding table." Do not place a table in the middle of a sentence. Column headings Use sentence case. Write concise headings that clearly describe the column content. Do not end column headings with punctuation, including periods, ellipses, or colons. Use the th element for column headings in HTML tables. Include the scope attribute for accessibility. Name Description Table placement Place each table directly after the sentence that introduces it. Do not place a table in the middle of a numbered procedure. Place the table immediately after the relevant step. If a table has footnotes, place them immediately after the table. Table captions If a page contains only one table, it does not need a caption. Place the table adjacent to the text that refers to it. If a page contains more than one table in close proximity, add a caption to each table. Start the caption with a number in the form Table NUMBER. followed by a brief description. Use sentence case. Do not place a period at the end of the caption. When referring to a captioned table from text, refer to it by number — for example, "as shown in table 2." Do not capitalize "table" unless it starts a sentence. In Markdown, place the caption as a bold line immediately before the table: **Table 1.** Supported DNS record types | Type | Description | | ---- | -------------------------------- | | A | Maps a domain to an IPv4 address | | AAAA | Maps a domain to an IPv6 address | In HTML, use the caption element as the first child of the table element:
Table 1. Supported DNS record types
Type Description
A Maps a domain to an IPv4 address
When to use tables The purpose of a table is to provide a scannable content experience. Tables display pieces of information that have some sort of relationship. Use tables for: Simple mappings of data and values Categories of things with examples Collections of things with different attributes Dates and descriptions, like a changelog A list of products with attributes When not to use tables Do not use tables to format a page. If your information does not fit within these guidelines, consider another method of presentation: Lists Subsections Tabs Details Markdown examples Add a table To add a table, use three or more hyphens (---) to create each column’s header, and use pipes (|) to separate each column. For compatibility, you should also add a pipe on either end of the row. | Syntax | Description | | ----------- | ----------- | | Header | Title | | Paragraph | Text | The rendered output looks like this: Syntax Description Header Title Paragraph Text Tip: Creating tables with hyphens and pipes can be tedious. To speed up the process, try using the Markdown Tables Generator. Alignment You can align text in the columns to the left, right, or center by adding a colon (:) to the left, right, or on both side of the hyphens within the header row. | Syntax | Description | Test Text | | :--- | :----: | ---: | | Header | Title | Here is this | | Paragraph | Text | And more | The rendered output looks like this: Syntax Description Test Text Header Title Here is this Paragraph Text And more Formatting text in tables You can format the text within tables. For example, you can add links, code, and emphasis. You can’t add headings, blockquotes, lists, horizontal rules, images, or HTML tags. Escaping pipe characters in tables You can display a pipe (|) character in a table by using its HTML character code ("|"). HTML examples For complex tables, consider using HTML. The following example is created with HTML: Field Description http.cookie `String` Represents the entire cookie as a string. Example value: session=8521F670545D7865F79C3D7BEDC29CCE;-background=light http.host `String` Represents the hostname used in the full request URI. Example value: www.example.org Large tables Generally, avoid large tables in documentation. If you have a unique use case, wrap the table in the component to make it responsive and scrollable. Header 1 Header 2 Header 3 Header 4 test test test test | Header 1 | Header 2 | Header 3 | Header 4 | | --- | --- | --- | --- | | test | test | test | test | Grammar import { DirectoryListing } from "~/components" Abbreviations Abbreviations include acronyms, initialisms, shortened words, and contractions (in most contexts, the technical distinction between acronyms and initialisms is not relevant; it is fine to use the word acronym to refer to both). Long and short versions of a word Some words have a long version and a short version, such as "application" and "app", "demonstration" and "demo", "synchronize" and "sync". The short versions of the words are not abbreviations, and if you use them, you do not need to put a period after them. If you are not sure whether a word is an abbreviation or just a short version of a longer word, here is a list of common abbreviations. If that does not settle the issue, use the speaking test: if you speak the short version as a word ("This is a demo version of the product"), you can usually treat it as a word and not an abbreviation. If a standard term in the Cloudflare dashboard is the long version of a word, use that over the shorter version to maintain consistency and distinctions. For example, customer applications on Cloudflare for Teams are not shortened to apps. Depending on the use case, application might be the preferred term, especially due to translation. When to spell out a term In general, when an abbreviation is likely to be unfamiliar to the audience, spell out the first mention of the term and immediately follow with the abbreviation, in parentheses. For all subsequent mentions of the abbreviation, use the abbreviation by itself. If the first mention of a term occurs in a heading or title, you can use the abbreviation and then spell out the abbreviation in the first paragraph that follows the heading or title. When deciding to spell out a term, consider your audience. If the majority of your audience is likely to recognize and understand the term, then you do not need to spell it out. For example, if you are writing documentation for developers that references an API, you do not need to spell out application programming interface. However, if you are explaining the general concept of an API to someone with no programming experience, spelling out the abbreviation can be helpful. In some cases, spelling out a term does not help the reader understand the term. For example, writing out portable document format does not help the reader understand what a PDF document is. In those cases, do not spell out the term. The following abbreviations rarely need to be spelled out: API DVD File formats such as PDF or XML HTML PC RAM REST Units of measure such as MB or GB URL USB Abbreviations not to use Prefer English terms over Latin abbreviations. Do not use i.e. or e.g. Instead, use that is or for example, respectively. One exception: avoid both etc. and and so on wherever possible, but if you really need to use one, use etc. Always include the period, even if a comma follows immediately after. Do not use Internet slang abbreviations such as tl;dr, IMO, FYI, or others. Use the most common form of a word. If the full spelled-out word is common and easily understandable, use that rather than abbreviating. For example, write approximately instead of approx. and versus instead of vs. Periods with abbreviations Follow these guidelines: Do not use periods with acronyms or initialisms. Put a period at the end of a shortened word, except for date and time abbreviations. If you write or say an abbreviation as a word (for example, app or sync), do not put a period after it. Do not use a period with an abbreviation for the name of a country, US state, or the District of Columbia (DC). i.e. vs e.g. While similar, these two Latin abbreviations carry very different meanings. i.e. stands for id est. Quite literally, it means "that is" (that = id, est = is). It can be replaced with "that is" or "in other words". The median compression ratio achieved by Gzip was 0.65% (i.e., the page was reduced to 0.65% of its size). e.g. stands for exempli gratia. Use this when introducing examples for something you have just mentioned. It can be replaced with "for example", or "like". Cloudflare products (e.g., Zero Trust, Magic Transit, etc.) offer network security and reliability. Acronyms Define new and unfamiliar terms. Acronyms and abbreviations can have an adverse effect on clarity, voice, and SEO. When writing or editing, some terms might be unfamiliar to some or all of the audience. When you spot a such an unfamiliar term, take one of the following tactics: If the term already exists, link to a good existing explanation. If your document is introducing the term, define the term. Do not use periods in acronyms. Acronyms are usually pronounced as their own word (like “QUIC”); for that reason, we do not place periods between each letter. Although initialisms are slightly different from acronyms — like “VPN” or “TLS,” they cannot be pronounced as their own word — we format them in the same way as proper acronyms in order to maintain consistency throughout our written content. Anthropomorphisms Avoid Anthropomorphisms in product content. Anthropomorphism is attributing human characteristics to inanimate objects. Computers do not think, want, worry, or do other things that are uniquely human. Capitalization Capitalize names of Cloudflare products, services, and features. Each product, service, and feature should be properly spelled and capitalized when used in any content, both to ensure consistency across all channels and to differentiate common performance and security technologies (for example: load balancing, bot management, and web application firewalls) from specific Cloudflare solutions (for example: Cloudflare Load Balancing, Cloudflare Bot Management, and Cloudflare Web Application Firewall). ✅ ❌ Rationale This interactive demo provides three different scenarios on how to utilize Cloudflare Rate Limiting to protect your endpoints from suspicious requests. This interactive demo provides three different scenarios on how to utilize rate limiting to protect your endpoints from suspicious requests. This demo is specific to a Cloudflare product (Cloudflare Rate Limiting), not a tutorial on utilizing generic rate limiting. The Cloudflare Web Application Firewall (WAF) sits on the same anycast network that powers our global CDN, HTTP/2, and web optimization features. Our web application firewall sits on the same anycast network that powers our global CDN, HTTP/2, and web optimization features. Cloudflare Web Application Firewall (WAF) is a specific product we offer and should be capitalized and identified with the Cloudflare name. Example of capitalization and pluralization usage for the Waiting Room When to use Waiting Room capitalized and singular: Naming the product: Waiting Room keeps wait times low by dynamically managing traffic. Page title: Access Waiting Room Preceded by “Cloudflare”: Cloudflare Waiting Room allows organizations to… Preceding a feature name: Waiting Room Event Scheduling When to waiting room(s) lower-case and in singular or plural: Used as an object: Your waiting room will begin queueing all visitors and will not allow any visitors to the path protected by your waiting room. Capitalize only the first word when at the beginning of a sentence: Waiting rooms are enabled on all subpaths, meaning you might be sending more traffic to your waiting room than anticipated. Capitalize only the first word when it is the title of a subsection: ### Waiting room template Common capitalization conventions ✅ ❌ Rationale CAPTCHA, reCAPTCHA Captcha, captcha, recaptcha, Recaptcha A CAPTCHA is a puzzle used to challenge users and ensure they are not bots. cloud Cloud, "cloud" The cloud is a network of remote servers used to store and maintain data. DDoS ddos, DDOS A DDoS attack is a malicious attempt to disrupt normal traffic of a targeted server. denial-of-service (DoS) denial of service, Denial-of-Service, Denial-Of-Service, Denial of Service, dos, Dos, DOS DDoS is a type of DoS attack. Enterprise, enterprise ent, ENT Capitalized - Refers to the official Cloudflare Enterprise Plan or a customer on the Enterprise plan. Sentence-case - All Enterprise customers are enterprise companies, but not all enterprises are Enterprise customers. Internet internet Disabling this option may cause all devices to lose Internet connectivity. SSL ssl SSL is an encryption-based Internet security protocol. TLS tls TLS is a security protocol designed to facilitate privacy and data security for communications over the Internet.. WAF waf WAF is a security system that helps protect web applications by filtering and monitoring HTTP traffic between a web application and the Internet. Zero Trust zero trust Cloudflare Access is a Zero Trust solution that secures inbound connections to your protected applications. Headings For headings, only the first letter of the first word should be capitalized. Normal capitalization rules still apply to the rest of the sentence. Compound words Whitespace is used in our blog posts and product content. For the sake of consistency, follow these conventions when using them: ✅ ❌ Example nameserver name servers Change your nameservers to Cloudflare's. hostname host name Add a *. SAN (wildcard) to the custom hostname certificate. data center datacenter Cloudflare updates the new setting across all of our data centers around the world. checkbox check box Select the Transfer lock checkbox before continuing the setup. When using compound words that have a preposition in them (think log in, or set up), they should be written as two separate words when they are verbs, and as one word when they are nouns. See these examples: Verbs Now you can set up Centrify, OneLogin, and other identity providers with Cloudflare Access. Learn how to start using SSO to log in to the Cloudflare dashboard. Make sure to back up your data. Nouns Having DAGs that can run simultaneously requires an Airflow setup that has been built and configured to scale. Share an account without sharing a login. This allows you to restore your data from the backup. Hyphenation Certain expressions should be hyphenated depending on their position and role in the sentence. As a general rule, when a compound word precedes a noun, it is called a modifier and should be hyphenated. When the same word comes after a verb, it has the role of an adverb and it should not be hyphenated. Examples: Modifiers Adverbs Keep up-to-date passwords secured and safe. Keep passwords safe by staying up to date Day-to-day maintenance means any daily processes which must be implemented for the equipment. The duration of a maintenance session will vary from day to day. This allows us to implement state-of-the-art security for our customers. This approach to authentication was the state of the art until a couple years ago. Contractions Avoid using contractions such as don't, won't, and can't. Parts of speech import { DirectoryListing } from "~/components" Nouns and pronouns Refer to the customer in the second person. Where this is not possible, use gender neutral pronouns. Do not use “one” as a pronoun. Make sure it is clear who or what pronouns are in reference to. Pronouns act as signposts to the subject of the sentence and should not be used so much that the subject is no longer clear. First person Substitute "we" or "I" with "Cloudflare" if you need to represent Cloudflare. You do not need to use "we" constantly. However, use it when it is the best choice grammatically. ✅ ❌ Cloudflare recommends you submit image or plain text files. We recommend closing your files before you restart your computer. Second person When you give instructions, use the polite command form with the second person "you" or in special cases "they" or "it". Referring to people Use "you" instead of "the user" when the audience is the user of a Cloudflare product. As a last resort, use passive voice if the subject is obvious or irrelevant. Possessives In general, avoid the 's construction to show possession by an inanimate object as doing so personifies the object. Example: the device's address. Prepositions You can put a preposition at the end of a sentence, but do not do it often. Your sentences can sound stilted if you try to avoid putting the preposition at the end. ✅ ❌ Open the application you are submitting an image for. Open the application for which you are submitting an icon. Slang Avoid all slang, especially derogatory or vulgar language. Ampersands Do not use ampersands, except where space is limited in the UI and where they are part of existing proper names. Colons import { Render } from "~/components"; Use colons to introduce unordered lists, tables, or images. Always precede lists, tables, and images with a full sentence. You can also introduce a list within a sentence. Commas Use the Oxford comma in lists of three or more items in a sentence. Use commas to separate clauses. Break up longer or difficult-to-read sentences into shorter chunks. Dependent clauses that start a sentence, end with a comma. (Learn more) Example: After you open the file, save it to your desktop with a different name. Oxford comma Use the Oxford comma. The Oxford comma should break up lists of three or more items in a sentence. Example: Stream for Free, Pro, and Business plans Without the Oxford comma, readers might misunderstand this header as free streaming for Pro and Business plans. Dashes Dashes look like hyphens, but are wider. An em dash is the widest type of dash. Dashes have a different purpose than hyphens. We use two types of dashes: Hyphen (-) Hyphenate compound modifiers that are placed before the noun. Compound modifiers that come before the noun require a hyphen to distinguish them from individual modifiers and nouns. Do not hyphenate compound modifiers that come after the noun. Hyphens are used in compound words and to express ranges. Examples: The most up-to-date software can be found here. It takes 24-48 hours for the data to upload. :::note Never include whitespaces around a hyphen. ::: Additional examples: ✅ ❌ Rationale Protect your Internet property from common vulnerabilities with our enterprise-class Web Application Firewall (WAF). Protect your Internet property from common vulnerabilities with our enterprise class Web Application Firewall (WAF). ‘Enterprise-class’ refers to the ability of something to scale with and handle the needs of large enterprises. A hyphen is necessary because the compound modifier comes before the noun. Our WAF is enterprise class. Our WAF is enterprise-class. ‘Enterprise class’ modifies ‘WAF.’ A hyphen is not necessary because the compound modifier comes after the noun. Em dash (—) Use em dashes to break up thoughts within a single sentence. Em dashes (—) or double dashes (--) with spaces around them may be used to break up thoughts within a sentence. Single dashes (-), or hyphens, are commonly used to write compound words/modifiers and should never be used to break up thoughts in this way. Shortcut for Mac users: Hold down Shift and Option keys, then press the Minus key Shortcut for PC users: Hold down the Alt key and type 0151 Dashes are used in pairs (in place of parenthesis) or alone (in place of a semicolon or colon). Examples: Cookies provide saved information about a user’s session to establish a “state” — in most cases, identity — as your browser makes a request. Embed yourself in the team — the best results will come when trust is built. :::note Following AP style guides, and to improve readability, we include whitespaces before and after the em dash. ::: Additional examples: ✅ ❌ Rationale The app has made security and privacy core to the company’s mission — and that is why it chose Cloudflare to provide an extra layer of protection. The app has made security and privacy core to the company’s mission—and that is why it chose Cloudflare to provide an extra layer of protection. An em dash with spaces on both sides is the appropriate way to distinguish the offset phrase at the end of this sentence. ACME has always looked deeply into two sources of traffic -- organic and direct traffic. ACME has always looked deeply into two sources of traffic - organic and direct traffic. A double dash is the appropriate way to clarify different types of traffic at the end of this sentence. A hyphen should not be used in place of a double dash. Additional dash information: Punctuation Character/HTML Code When to use in Cloudflare documentation Justification Hyphen - Negative numbers, compounding nouns, compound adjectives, removing ambiguity, certain prefixes, certain units Use a hyphen instead of an en dash. Minus − Do not use Em Dash — Empty table cells Heavy use of the em dash creates choppy sentences that might annoy readers. En Dash – Copyright year spans To avoid possible confusion, the word "to" should be used instead of an en dash in a range of numbers because the en dash can be misinterpreted as a minus sign. Exclamation points Avoid using exclamation points in most writing! Exclamation points are appropriate for success messages or screens in the UI. Punctuation marks and symbols import { DirectoryListing } from "~/components" Percentages Use the % symbol for percentages instead of “percent” after the numeral. Periods Do not use periods in titles or headings. Only use periods for complete sentences in body text. Quotation marks In general, avoid the 's construction to show possession by an inanimate object. Doing so personifies the object. Example: the device's address. Usage Do not use “ ” ‘ ’, which are double or single typographer's ("curly") quotation marks. Use standard quotation marks instead. Semicolons Avoid semicolons when possible. Break down long explanations into shorter, simpler sentences.