Clicking a nav link inside the builder's preview navigated the iframe to that page's live URL. The canvas then showed one page while the section list edited another, with nothing to tell you. Fixing it meant deciding what an iframe inside an editor is actually allowed to do.
The builder in Atelier is a three-pane editor: sections on the left, the real page in an iframe in the middle, settings on the right. It has been that since the first release, and it had one exit.
Editing two pages meant: back arrow, the Pages list, find the row, Open builder. Five steps each way, and a client fixing a phrase in a header and the same phrase in a footer does that a dozen times in an afternoon.
The part that was actually wrong
The preview renders the real page through the real layout, which is the whole argument for it. A real layout has a real nav, with real hrefs.
So clicking Work in the preview navigated the iframe to /projects. The public version of it. The editor did not know, because nothing told it: the iframe just followed a link, the way an iframe does.
What you were left with was a canvas showing the projects page and a sidebar listing the home page's sections. Editing a section then changed a page you were not looking at. No error, no warning, no way to tell except noticing that the section list stopped matching the screen.
That is worse than the missing feature. A preview that silently stops previewing the thing you are editing undermines the one property the editor is built around.
What an iframe in an editor is allowed to do
The decision underneath the fix: the preview should never navigate itself. It is a preview of one page, and the moment it points somewhere else it is a browser wearing a preview's clothes.
So every click on an <a> inside the preview is now intercepted and posted up to the editor, which decides:
- A page on this site opens in the builder. You are now editing the page you clicked.
- Anything else, an external site or one of the host app's own routes, opens in a new tab. The builder stays exactly where it was.
Plus a Pages panel in the icon rail for when you know where you are going: every page grouped by type, a search box, the current one marked.
Both go through a real navigation rather than swapping the record inside the Livewire component, so the address bar names the page being edited. Refresh works. Back works. Sending someone the URL works. Swapping state in place would have left the address bar lying, which is the same class of problem I was fixing.
The resolver, and the rule I refused to write twice
"Which page is this URL" already existed, in the public controller, and it is subtler than it looks:
// /{slug} is the default locale. /{locale}/{slug} is everything else.
// The first segment is a locale only when it names one.
Get that wrong and /services/web-design reads services as a language and serves the services page with a 200. That exact bug shipped in August and took a while to spot, because a 200 with the wrong content looks like a content problem, not a routing one.
The editor needed the same answer. Writing a second copy of a rule that has already caused one silent bug is how you get the same bug twice, in two places, at different times. It moved into a PageResolver that both call, which is the smallest amount of work that makes a second occurrence impossible.
One thing I found on the way
While handling clicks in the preview I noticed forms were not handled at all. A block with a form, posting to the app's own route, submitted for real from inside the editor. On the demo site that meant a booking request from a draft page landing in the client's inbox as a genuine lead.
Submits are blocked in the preview now. Nobody reported it, because nobody had built a form block yet. Writing the demo site did that a week earlier, which is the whole argument for keeping a demo that behaves like a client project.
Where it stands
Shipped in v1.0.0. Click a link in the preview and you are editing that page. Click Pages and pick another. The URL follows.
The measure I care about: the number of times you have to leave the builder to do a normal afternoon's work went from a dozen to zero.