---
title: "How it works"
manual: "Frontend Edit"
version: "2.6"
source: "DeveloperCorner/Architecture.rst"
rendered: "2026-10-01T07:11:45+00:00"
---

# How it works {#architecture}

Frontend Edit deliberately keeps the client dumb: the server decides what may be
edited, the browser only renders it.

![Frontend Edit Screencast](../Images/intro.gif)

## Request flow {#request-flow}

1.  A PSR-15 **middleware** injects the CSS and JavaScript before `</body>` —
    but only if a backend user is logged in. For regular visitors the response
    is untouched.
1.  With [frontendEdit.markerBasedDetection](../Configuration/SiteSettings.html#confval-frontendedit-markerbaseddetection) enabled, the PSR-14
    listener `ContentElementMarkerEventListener` wraps every rendered content
    element in [render markers](../Integration/TemplateRequirements.html#render-markers). A TypoScript condition
    limits this to backend users, so their pages are cached separately.
1.  On page load the script collects the [content element IDs](../Integration/TemplateRequirements.html#template-requirements) from the DOM and calls the AJAX endpoint
    `/typo3/ajax/xima-frontend-edit/edit-information`.
1.  The **server** filters that list — backend user permissions, the
    [site settings filters](../Configuration/SiteSettings.html#site-settings) (pages, doktypes, CTypes,
    UIDs) and translation resolution (see [Languages](Languages.html#languages)) — and returns only
    the elements the current user may actually edit, together with the menu for
    each of them.
1.  The script **assigns** each menu to its DOM element and renders the edit
    button, the context menu and, where enabled, insert buttons and drag
    handles. The menu entries link to the corresponding edit views in the
    TYPO3 backend.

> [!NOTE]
> Because the menus are delivered through an uncached AJAX request, frontend
> editing works on fully cached pages without polluting the page cache.

## Permissions are decided server-side {#permissions-are-decided-server-side}

Permissions are never evaluated in the browser. Every action link is generated
server-side from the backend user's actual permissions, and write operations
such as [drag & drop](../Usage/DragAndDrop.html#drag-and-drop) re-check those permissions before
touching a record.

## What the client needs {#what-the-client-needs}

The only hard requirement is that content elements are identifiable in the
rendered HTML — `fluid_styled_content` already covers this:

**Example HTML output of a content element**

```html
<div id="c10" class="frame frame-default frame-type-textpic frame-layout-0">
    ...
</div>
```

> [!NOTE]
> **See also**
>
> [Template requirements](../Integration/TemplateRequirements.html#template-requirements) covers custom templates, EXT:container,
> EXT:dce and the optional markers.
