Leave JEKYLL_ENV unset so Umami stays off:
npm install
bundle install
bin/dev
That starts Jekyll (--livereload --verbose --incremental) and a PostCSS watcher from Procfile.dev.
assets/css/main.src.css is the source. npm run build:css / npm run watch:css write assets/css/main.css (gitignored). We do not use jekyll-postcss — it passes the whole stylesheet on the CLI and fails with Argument list too long once the file is large.
CI and deploy use production env (Umami on, CSS minified):
npm ci
JEKYLL_ENV=production npm run build:css
JEKYLL_ENV=production bundle exec jekyll build
/pricing loads plan prices and limits from committed _data/plans.json (Solo audit retention is 5 days).
Optionally sync from Radar by setting PLANS_API_URL:
PLANS_API_URL=https://armor.dotenvx.com/public/plans bundle exec jekyll serve
PLANS_API_URL=http://localhost:3000/public/plans bundle exec jekyll serve
Plans are priced by users, audit retention, and included monthly audited accesses. Armored keys are unlimited on every plan; additional usage is disclosed per 1,000 events at $0.20 on Solo, $0.10 on Team, and $0.025 on Business, charged only for complete blocks of 1,000 extra events. Collection timing and payment mechanics are not yet defined. This repository contains public copy only; it does not implement billing.
Use layout: prose for pages with a title, description, and ordinary Markdown body.
The layout renders the hero and wraps the body in design-content-width design-prose,
so paragraphs inherit the same typography as design-paragraph. Headings, links,
lists, and code use the existing prose styles. No paragraph includes or HTML wrappers
are needed. An empty body renders only the hero.
---
layout: prose
title: Agentic Dotenv
description: "The dotenv you love–now ready for agents."
permalink: /agents
hero_visual: components/joined-slab-hero.html
---
This is paragraph 1.
This is paragraph 2 with **emphasis** and a [link](/docs).
## A heading
- A list item
- Another itemhero_visual is optional; it names an include for the illustration above the title.
Keep illustration markup and behavior in that include, leaving the page for writing.
See agents.md for a minimal example.
All docs content columns style ordinary Markdown paragraphs like design-paragraph,
including the existing spacing inside steps. Use plain paragraphs, backticks,
**bold**, and [links](/docs) in docs-cli and docs-quickstart page bodies.
Use ## Heading and ### Subheading for section headings; they inherit the docs
heading styles. To preserve a specific link target, put {: #reference} on the
line immediately below the heading. Otherwise, an anchor is generated from its text.
Hand-built guides can keep their interactive examples and step layout while writing the step text in Markdown:
{% capture step_content %}
## Install
Get the Dotenvx CLI.
This is another paragraph with a [link](/docs/install/).
{% endcapture %}
{% include components/design-step.html content=step_content markdown=true %}Keep Markdown at the left margin: four leading spaces mean an indented code block.
For text inside a custom HTML container, add markdown="block" to that container
(including nested containers such as <details>). Use fenced code blocks for editable examples with copy controls and highlighting.
Keep choice components for tabs and codeblock includes for dynamically supplied code.
/search is the dedicated search page. Press / on any public page to open the search modal. Both load /search.json (generated at build from pages + posts). Tune ranking in _data/search.yml (boost, aliases). Optional per-page front matter: search_boost, search_aliases, or search: false. Committed queries send a production Umami Search event (query, source, results) — Events → Properties.
Use ordinary Markdown fences. They render the same styled, highlighted codeblock and copy button as the Liquid component:
```ruby
env "KEY"
```By default, Copy copies the displayed code. For a transcript whose output should not be copied, add a Kramdown attribute line immediately after the closing fence:
```console
$ dotenvx encrypt
◈ encrypted (.env)
```
{: copy="dotenvx encrypt"}console (also cli or shell-session) highlights $ commands and their
backslash continuations, keeps ordinary output neutral, and colors dotenvx status
lines amber. Use bash for shell scripts without prompts, dotenv for .env files,
and text for plain output. Unknown languages fall back to escaped plain text.
Optional fence attributes:
{: copy="false"}hides the copy button.{: .design-codeblock--nowrap}keeps long lines horizontally scrollable.{: label="Example output"}supplies an accessible label.- Combine attributes on one line as needed.
Copy text can span lines inside its quotes. Escape embedded double quotes as
\"; escape closing braces as \}; other backslashes stay literal. For example:
```console
$ git add .env
$ git commit -m "encrypt .env"
```
{: copy="git add .env
git commit -m \"encrypt .env\""}For dynamic or reused examples, the existing component still works:
{% include components/design-codeblock.html value=example language="javascript" %}
{% include components/design-codeblock.html value=transcript format="cli" copy_text=commands %}Choice-code items and quickstart front matter retain their existing language,
format, and copy settings. _plugins/design_codeblock.rb shares the HTML renderer
between fences and includes, including fences rendered through markdownify in steps.
Restart Jekyll after changing this plugin, and clear its Markdown cache with
bundle exec jekyll clean when updating renderers (or build with --disable-disk-cache).
The renderer in _plugins/design_syntax.rb and palette in assets/css/design-syntax.css
are mirrored in Radar (lib/design_syntax.rb and the syntax section at the end of
app/assets/stylesheets/application.tailwind.css). Keep both copies aligned. Dotenv
has a dedicated lexer for assignments, comments, multiline values, and interpolation.
Run bundle exec ruby scripts/test-design-syntax.rb and
bundle exec ruby scripts/test-design-codeblocks.rb, then npm run build:css and
bundle exec jekyll build. Preview /docs/quickstart/, /docs/env-file/, and
/docs/cloudflare/ in both themes. Radar's /design/codeblock is the specimen gallery.
Every public HTML page needs a descriptive title, a page-specific description
(or a blog excerpt), and one main h1. The shared head supplies canonical URLs,
Open Graph and Twitter cards, JSON-LD, and RSS discovery. seo_title optionally
sets the complete search title without changing the visible heading;
social_title can separately customize sharing copy.
Docs automatically receive contextual search titles and linked breadcrumbs from
existing parent pages, crumbs, and eyebrow_href. Keep those links pointed at
canonical pages. Use noindex: true for utility pages; the SEO generator also
excludes these from the sitemap. Redirects should use redirect_to or
redirect_from, with each old URL defined once and pointing to its final page.
Do not add generated timestamps as last_modified_at; use actual content changes.
Validate a production build (also enforced before deployment in CI):
JEKYLL_ENV=production bundle exec jekyll build
bundle exec ruby scripts/test-seo.rbThe check covers every indexable page, title and canonical uniqueness, descriptions, headings, social metadata, valid JSON-LD, breadcrumb destinations, sitemap coverage, and robots rules. An optional first argument selects another build directory.
Side paths are optional Markdown pages that open in a right-hand drawer from a
guide. Each also has a normal URL and works without JavaScript. Create a page with
layout: docs-side-path, title, description, permalink, parent_url,
parent_title, and side_path_kind (Alternative or Troubleshooting) in its
front matter. Write its body as ordinary Markdown, including existing codeblock
attributes for copy text and package managers.
Link to it from a docs-markdown guide:
[**Not using Armor?** Alternative →](/docs/nextjs/share-private-key/){: .side-path}
[**Seeing encrypted text?** Troubleshoot →](/docs/nextjs/encrypted-text/){: .side-path .side-path--troubleshooting}Use “Alternative →” for alternative paths and “Troubleshoot →” for fixes.
Keep the attribute on the same line as the link so it applies to the link, not
the surrounding paragraph. Use {: .side-path-inline} for a link inside prose.
The shared drawer supports Escape, backdrop dismissal, focus restoration, reduced
motion, and full-width mobile reading. Package-manager choices stay synchronized
with the parent guide. “Open page” provides a bookmarkable standalone view.
The Jekyll build exports docs/nextjs.md to /docs/nextjs.md alongside the HTML guide. _plugins/raw_markdown_exports.rb removes front matter and styling attributes, labels package-manager examples, converts browser previews to text, and makes internal links absolute. Code examples are preserved. The three Next.js side paths are also exported under /docs/nextjs/*.md. Links between these four pages point to their Markdown exports, preserving section anchors. Other internal links stay on HTML pages. Deployment-variable components become dotenv examples.
Run bundle exec ruby scripts/test_raw_markdown_exports.rb to check the export.
The reusable components/docs-agent-button.html takes prompt and markdown_url parameters and uses the consistent label “Onboard your coding agent.” On docs pages, set agent_prompt and markdown_url in front matter to show it in the hero. The button copies the prompt followed by “Fetch and follow it.” Currently enabled only for Next.js.
The newsletter page, blog index, and article footer share _includes/components/newsletter-signup.html.
The form posts to https://armor.dotenvx.com/public/newsletter/subscribe with
email, source (newsletter, blog, or blog-post), and an empty website honeypot.
Armor sends a confirmation email; subscribers enter the newsletter list only
when they confirm. The source is stored on the confirmed subscriber.
Deploy the matching radar backend changes before deploying these forms.
The endpoint must allow POST requests from https://dotenvx.com and
https://www.dotenvx.com. Local signup submissions still target production;
use the Armor request specs to test without sending real emails.