Configuration
ezu/config.rb is Ruby evaluated by Ezu, so every setting is a method call. Only adapter is required.
After reading this page, you will know every setting and what it changes.
adapter
How Ezu boots the app. :rails or :command, with options; see Adapters.
adapter :rails, prepare: %w[db:schema:load tailwindcss:build], env: { "FEATURE_X" => "off" }
locales
The languages every flow runs in. Defaults to "en". Each locale doubles the slots, and the run time with them unless your machine has cores to spare.
locales "en", "ja"
bin/ezu map --locales en runs a subset.
timezone
The browser's time zone. Defaults to "UTC".
moment
The moment every run happens at. Time stands still at it during the first step and moves 3 seconds between steps, in the app and in the browser. Defaults to 6 January 2026, 01:00 UTC.
moment Time.utc(2026, 11, 10, 1, 0) # a Tuesday morning in Tokyo
Pick a moment after your seed's dates, so "3 days ago" stays "3 days ago".
port
The first slot's port. Defaults to 37211, and each slot takes the next one. Ports are fixed because share links and QR codes contain them.
seed
A script, relative to ezu/, run inside the app once per slot. See Seed test data.
cookies
A block returning the cookies to set before each flow. It gets the slot's locale:, the slot's seed: and the flow's signed_in:.
cookies do |locale:, seed:, signed_in:|
[ { name: "locale", value: locale },
({ name: "session_id", value: seed.fetch(:session_cookie), sameSite: "Lax" } if signed_in) ].compact
end
dark_mode
A block that switches an open page into the dark theme and back, the way the app does when the system theme changes. With it, every state gets a dark screenshot as well. Ezu also emulates prefers-color-scheme: dark while it runs.
dark_mode do |page, dark|
page.evaluate(<<~JS, arg: dark)
(dark) => dark ? document.documentElement.setAttribute("data-theme", "dark")
: document.documentElement.removeAttribute("data-theme")
JS
end
exclude
Routes that are not pages a person sees, matched against their page id (controller#action). They are left off the map entirely.
exclude %r{\A(api|admin|rails|active_storage)(/|#)}, /\Ahealth#/
unreachable
Routes a person can't reach yet, with the reason. The viewer lists them as unreachable, and a flow landing on one fails the run, which tells you to remove the declaration.
unreachable "group_attachments#show", because: "the attachments flag is off for everyone"
areas
Groups pages in the viewer, by page id. The first matching area wins; anything else is in "Other".
area "Public site", /\A(home|pages|blog_posts)#/
area "Groups", %r{\A(groups|group_)}