Edit Jekyll's Liquid layouts, not just the posts
The Jekyll editors you already know edit posts. This one edits _layouts/default.html and the includes under it, by matching the element you clicked back to the markup in your own template. Your repo stays the source of truth. Pro, early access, opt-in.
Can I edit a Jekyll site visually without moving to a CMS?
A Jekyll site keeps its markup in Liquid layouts and its words in Markdown with front matter, so editing it visually means two different jobs. The content side is well served — every git-backed CMS built for Jekyll does it. The layout side is where the loop still hurts: change _layouts/default.html, rebuild, refresh, squint. PortBay attaches an edit bar to your running jekyll serve, so clicking an element in the page and retyping it writes into the Liquid layout that emitted it, in your repo. Liquid tags themselves are left alone: a value printed by page.title is not in the layout as words, so PortBay writes it to that page's front matter instead of rewriting your template. Structural edits — moving, wrapping, converting an element — are refused rather than guessed. Pro, early access, opt-in.
Verified against the product, 2026-09-05.
A Jekyll site and its _layouts
PortBay serves your Jekyll site at its own .test URL with trusted HTTPS and dispatches board cards into it. The visual editor edits that same running site in your real browser — one live page, not a multi-frame design canvas.
Your first Liquid layout edit
Four steps. Nothing is added to your Gemfile, because nothing in a Ruby build chain would help here — Jekyll runs on the text-matching lane and that is stated rather than papered over.
- Install PortBay and add your Jekyll site
- Turn the visual editor on
- Open Edit in browser
- Change the layout, or change the page
Install PortBay and add your Jekyll site
Homebrew installs the app and the bundled portbay CLI. PortBay recognises Jekyll by a root _config.yml together with a _layouts/ or _posts/ directory — both halves are required, because a _config.yml on its own is not specific to Jekyll — then serves the site at its own .test hostname over trusted HTTPS.
brew tap portbay-app/portbay && brew install --cask portbayTurn the visual editor on
It ships to Pro under early access and is off by default. Sign in to Pro, then flip the Early Access toggle. The open-source build does not include the editor at all — it is not compiled in.
Settings › Account › Early AccessOpen Edit in browser
The project's Visual editing section has one button. It opens your normal browser at your normal .test URL with the edit bar docked at the top, booting in Preview mode where the site behaves as it always does. Navigate to the page you want, then switch to Edit.
https://mysite.test/about/Change the layout, or change the page
Element edits — text, classes, attributes — are located in the layout or include that emitted them and rewritten there. The Page settings panel writes title and description into that page's own front matter instead, because a title written into _layouts/default.html would apply to every page that names it and a title written into _site would be erased by the next build.
Where an edit lands in a Jekyll project
A Jekyll page is two files: the layout that draws it and the Markdown that names that layout. Which file changes depends on what you clicked, and PortBay picks by what the markup actually is.
Nothing is ever written into _site. A change there would look right until the next build removed it, which PortBay treats as a failure rather than a result.
<!-- _layouts/default.html --><!doctype html><html> <head> <title>{{ page.title }}</title> <!-- Liquid output. Not words in this file, so the Page settings panel writes the title into about.md's front matter. --> </head> <body> <nav class="topbar"> <a class="brand" href="/">Acme Boats</a> <!-- literal markup: text, class and href all edit, here --> </nav> {{ content }} {% for item in site.footer_links %} <a href="{{ item.url }}" class="foot-link">{{ item.name }}</a> <!-- class="foot-link" edits. The name and url do not: they come from _config.yml, not from this template. --> {% endfor %} </body></html> ---# about.md — the page that names the layouttitle: "About us"layout: default---
The pieces underneath
Visual editor
Click an element on your running site in your own browser and edit its text, classes and styles straight into the source file, across 21 stacks.
Explore →CLI
brew install --cask portbay ships a full CLI over the same Rust core: lifecycle, logs, doctor, config-as-code and the board, with --json.
Explore →Asked before downloading
CloudCannon, Siteleaf and Decap are content editors for Jekyll: a form over front matter and Markdown, committed back to git, aimed at the person writing the posts. This is aimed at the person maintaining the theme. The element you click is found in _layouts or _includes and the bytes that change are in your own Liquid file. The two solve different problems, and if what you need is a writing interface for a colleague, a content CMS remains the better answer.
PortBay requires two markers: a _config.yml at the root, and either a _layouts/ or a _posts/ directory. Both halves are needed on purpose. _config.yml is a common enough filename that treating it as a Jekyll signal on its own would misidentify other projects, so a directory that has the config and neither directory is explicitly not detected as Jekyll.
Yes, because nothing here depends on where the site is deployed. PortBay serves your local checkout on a .test hostname with trusted HTTPS and edits the files in it; the result is an ordinary change to your working tree that you commit and push exactly as you do now. There is no build service to connect and no account to link — the edit is a diff, and git is still your deploy pipeline.
Jekyll Liquid tags are left alone. A value printed by a Liquid expression is not in the layout as words, so rewriting it would mean rewriting your template logic into a literal — which would change the page for every route that uses that layout. PortBay refuses those edits and, where the value has a real home, sends you to it: a page title lives in that page's front matter, so that is where the Page settings panel writes it.
Not on Jekyll. Structural edits are refused here rather than guessed at, because without a source coordinate on the element there is no way to be certain which occurrence of that markup you meant — and a wrong structural edit to a shared layout is a broken site rather than a wrong word. Text, class and attribute edits, plus page settings, all write. PortBay tells you which mode a project is in instead of degrading quietly.
Yes. It is stored under that page's own portbay_head_code and portbay_body_code front-matter keys, and PortBay installs a small include in the project once so your layout prints them into the real head and before the closing body tag. It is per-page rather than site-wide, and it lives in your content file, so it travels with the page in git.
No. It is a PortBay Pro feature, still in early access behind an opt-in toggle in Settings, and it is not compiled into the open-source build. It refuses to run while the site is shared over a public tunnel, and the edit bar works only on local .test hosts. Serving Jekyll on a real .test domain with trusted HTTPS is in the free app.

Give your projects and your agents a real local home.
Download for macOSFree & open source · macOS 11+ on Apple Silicon · Pro from $10/mo