Content Preview: The Journey of a Side-By-Side Budget Idea

In this report, Łukasz Uznański shares the story behind his community budget idea and presents the first results of the new Content Preview extension.

Introduction

The idea of side-by-side content has always been haunting me. I knew other CMS platforms had this type of view, and it was frustrating to see TYPO3 missing it. For a long time, I thought: “It would be great to have something like this in TYPO3.”

At first, I imagined something simple, like an edit button directly on the frontend. But then, during a Developer Days event, I talked with UX team members. Someone mentioned Sulu CMS and their solution.

The TYPO3 UX team had indeed been shaping concepts for quite some time — sketches, user flows, and interface guidelines — and was genuinely eager to find a developer ready to turn this vision into reality. Seeing these ideas move from drafts to a working implementation was exactly the partnership they’d been hoping for.

This significant improvement to the page-editing experience in the TYPO3 backend was proposed for the v14 roadmap, but it lacked available development resources to bring it to life. The idea was clear and validated; what was missing was dedicated engineering time to implement it.

That was the moment I thought — maybe this could be more than just a button on the frontend, and that I can implement something similar to other solutions on the market. I submitted a community budget idea for Q3 this year, Side-by-side live preview and page content editing, which was approved.

First Attempts: Separate Module and Two Iframes

So I started experimenting. My very first idea was to create a completely new TYPO3 module, separate from the Page Module. Inside this module, I placed two iframes side by side:

  • Left iframe — the standard Page Module
  • Right iframe — the rendered frontend page

The mechanism was simple: from TYPO3 I got the current page ID, built the corresponding frontend URL, sent the request, and injected the resulting HTML directly into the iframe.

When I first saw the page rendered this way, I thought that this actually works. Maybe it isn’t that hard!

Adding Edit Buttons

The next step was to make the preview interactive. I wanted clickable “Edit” buttons inside the frontend preview. To inject them, I tried several approaches:

  • Custom parameter — fastest and easiest, also extensible for future preview improvements (chosen)
  • Custom header — not always supported, more limited
  • Cookie-based approach — possible, but with limitations

By appending a custom parameter to the frontend request, I was able to inject extra markup — small edit icons that linked directly to TYPO3’s record editing. Suddenly the frontend preview became usable.

Highlighting Edited Elements

After edit buttons worked, I faced the problem of highlighting which content element was being edited. That required detecting record edit routes and visually marking the corresponding frontend element.

Here I hit a wall: I needed cross-iframe communication. The only option seemed to be using postMessage, but that quickly got messy:

  • I had two iframes that needed to talk to each other
  • Highlighting methods were different per page
  • It was unclear where to put the configuration

The Docheader Problem

I thought: “Maybe I’ll add a configuration bar in the docheader.” But the Page Module already had its own docheader, and adding a second one in my iframe-based module was confusing.

The alternative was to override the Page Module and control its DocHeader — but I didn’t want to go that route. It felt hacky and fragile.

When I talked with Tymoteusz Motylewski, he confirmed my suspicion: this was not a good design. We should not duplicate navigation, and having two separate iframes communicate was a recipe for trouble.

Changing Direction: A Better Architecture

Then I spoke with Marcin Sągol, and his advice changed everything: “Instead of building a new module with two iframes, why don’t you extend the existing Page Module and just place a div inside it?”

This was a breakthrough. By integrating the preview directly inside the Page Module:

  • I only needed one iframe
  • No duplicate navigation
  • Communication was much simpler
  • Language handling worked almost out of the box (almost!)
  • I didn’t need to override the docheader

Even better: I realized I no longer needed to fetch the frontend HTML separately. I could simply make a request with a special parameter, intercept it in TYPO3 middleware, and alter the output on the fly - injecting buttons and scripts. This approach was clean and efficient.

What to Put Inside the Iframe? Possible Strategies

When working on this, I asked myself: “What exactly should I load into the preview iframe?” I considered several options:

  1. Direct frontend URL with a query parameter or header
    • Easiest and most flexible
    • Works with both standard and headless frontend
  2. Fetch frontend HTML and inject it directly into the iframe
    • Works, but inefficient (browser flooded with data)
  3. Fetch frontend HTML, save it to a temporary file, and load from there
    • Technically possible, but messy (requires file cleanup and maintenance)

For now, I went with option 1, as it leaves the door open for other approaches later, but keeps things simple.

UX and Frontend Input

At this point, I worked closely with frontend developer, Paweł Zieliński. We debated how to present configuration options to editors. Two ideas came up:

  • A top bar inside the preview
  • A floating hamburger menu

The hamburger menu won. It felt more modern, lightweight, and avoided duplicating TYPO3’s existing navigation.

The menu now stores options like:

  • Whether to highlight content elements or not
  • Which highlighting method to use
  • Other preview configurations

Communication Challenges

Another big issue was iframe communication. We needed messages to:

  • Highlight the element currently being edited
  • Alter HTML in the iframe in some cases
  • Keep backend and frontend views in sync

But relying on postMessage was a problem because it doesn’t work across domains. That means with multiple root pages (different domains) you hit re-login problems.

The solution came from previous experience with interactive step-by-step guides. Instead of post messages, we injected custom JavaScript through middleware. This allowed secure, two-way communication between TYPO3 and the frontend preview.

This approach works in both standard HTML and headless setups, but has other downsides:

  • It’s not that easy to work with hovers on the iframe, it’s not 100% accurate
  • For now, we don’t have all the features from the original approach, as it requires rewriting.

New approach:

Experimental Features: Navigation Inside Preview

One of the most exciting experimental features is the ability to navigate TYPO3 directly from the preview, without using the Page Tree. It’s enabled by default but you can disable it via Settings.

Here’s how it works:

  • Internal links are annotated with the page UID (using AfterLinkIsGeneratedEvent)
  • Clicking such a link triggers backend navigation to /typo3/module/web/layout?id=303
  • You can move around the site in preview mode, while TYPO3 updates accordingly

There are still open issues:

  • DataProcessor-generated URLs don’t yet get parameters
  • Cross-domain links don’t work

But when I showed it to Rachel Foucard, she said that my approach is fine, and that this kind of navigation would allow editors to bypass the page tree entirely during their work, ultimately adding value for end users.

Current State

The project started small, but it grew into something much bigger. I even created a new organization, T3-UX, to support it. The extension is now called Content Preview (content_preview), because that name best describes the idea.

Right now, there are two working approaches for Content Preview, which you can switch by changing the feature flag:

  • PostMessage communication — more features, but domain-limited
  • Custom JavaScript injection — experimental, cleaner, but missing some features

Both are usable, and both have pros and cons. Deciding which way to go will require input from the TYPO3 community.

The real challenge to face in the extension is how to make it work for the majority of use cases, as the frontend may differ from implementation to implementation.

Roadmap: Where Content Preview Should Go Next

This is just the first iteration, and while it currently delivers value, there are many ways we can expand it for even greater benefits. Content Preview is available as a public extension, and we should improve it together as a community. Here are some ideas for the future:

  • Start/Stop Date Simulation — Content scheduled for the future or set to expire needs simulation. This feature will allow editors to see “what the site will look like tomorrow at 10:00.”
  • Frontend User / Group Simulation — Many sites personalize content by user or group. Editors should be able to simulate different roles instantly.
  • Workspace Handling — Supporting workspaces is critical for TYPO3. Editors must preview unpublished changes in real workflows. This requires advanced state handling in middleware.
  • Preview Modes and Window Options — Editors work differently. Some want a floating window, others prefer a new tab. Content Preview should adapt to both.
  • Better Cross-Domain Support — TYPO3 installations with multiple rootpages and domains should not require relogin. This is a long-term technical challenge, but critical for usability.

Conclusion

Looking back, this project started as just a small idea — “Let’s put edit buttons on the frontend.” But step by step, through experiments, wrong turns, and better solutions, it evolved into something much bigger.

Now we have Content Preview:

  • A working proof of concept that is usable and can support editors in their day-to-day work
  • Two possible approaches to solve the problem
  • Experimental navigation directly inside preview
  • A clear roadmap for the future

This is not just about technology — it’s about making TYPO3 more editor-friendly, more modern, and more competitive.

Get Involved

The story isn’t finished. The next steps depend on the TYPO3 community. Our number one goal is community adoption. The more editors and integrators use Content Preview, the more feedback we get — and the faster it can mature into a standard feature.

We encourage you to experiment with the extension, give feedback, and report any issues.

Check out Content Preview on GitHub!