Technical documentation / Ston Handoff

Every part of Handoff,
explained.

Installation, a step-by-step tutorial for every screen, the full settings reference and the architecture underneath — the complete documentation for Ston Handoff and the Pro add-on.

  • WordPress 6.6+
  • PHP 7.4 – 8.3
  • Elementor 3.x & V4 atomic
  • Multisite ready
  • No front-end assets

01 / At a glance

Technical strengths

What makes Handoff different from hiding buttons in the editor.

Data level

Locks the data, not the UI

Every write to _elementor_data is checked on the server — editor saves, REST, WP-CLI and other plugins included.

Every format

Legacy, containers and V4

One document walker understands sections and columns, flexbox containers and atomic (V4) elements, so a lock survives a rebuild.

Safe rollout

Watch before you enforce

Locks start in warning mode: design changes are logged but kept, so a lock never blocks legitimate work before you trust it.

Audit

Before / after log

Every structural change is recorded with user, element and the old and new value — with WordPress privacy export and erase.

Admin

A dashboard per client type

Profiles hide menus, screens, widgets and notices. Hidden screens are also blocked by direct URL (HTTP 403).

Light

Nothing on the front end

No front-end scripts or styles and no external calls. One option, autoload off, plus dedicated tables.

02 / Install

Install and activate

01

Install the free plugin

Download Ston Handoff from ston.ae/download/ston-handoff and upload it in Plugins → Add New → Upload. Activate it.

02

Check the requirements

WordPress 6.6+, PHP 7.4 – 8.3 and Elementor (free is enough). A Handoff menu appears in the admin.

03

Add Pro (optional)

Upload Ston Handoff Pro next to the free plugin. Pro adds hard locks, content intake, CSV export, tips and a longer log.

04

Activate the license

Copy the key from My Account → Licenses on ston.ae and paste it on the License screen Pro adds under Handoff. Updates then arrive in Dashboard → Updates.

03 / Tutorial / Locks

Lock a page

Handoff → Locks lists every Elementor document. A lock is set per document.

01

Pick the document

Search for the page or template and open it. Bulk actions can lock several documents at once — bulk locks start in warning-only mode.

02

Choose the level

Content: only allowed props (text, images, links) can change. Frozen: no Elementor change is kept; title and excerpt stay editable in WordPress.

03

Capture the baseline

Click “Capture the current page as the new baseline”. Saving the page in Elementor as a designer refreshes it automatically.

04

Adjust allowed props

Optional: list extra props per widget type for this document. Leave empty to use the site-wide list from Settings.

05

Test as the client

Log in as a client user, edit and save. Then tick “I tested editing and saving this document as a client”.

06

Turn on the hard lock (Pro)

“Hard lock: revert locked changes on save”. Without it, violations are saved but logged — the free plugin always works this way.

07

Protect the global design

At the bottom of Locks, lock Global design (Site Settings): global colors, fonts and classes change every page at once.

08

Watch the attempts

“Recent attempts” lists blocked changes per document. Frequent attempts mean the client needs an extra allowed prop.

04 / Tutorial / Profiles

Give each client a simple admin

Handoff → Profiles. A profile is a full configuration for one kind of client: menus, screens, dashboard, checklist, tips and support button.

01

Start from a task

“What should this user do?” — Only writes articles, Updates page content, or Adds products. The choice pre-selects what to hide next.

02

Hide what they do not need

Tick menus and screens to hide. Hidden screens return 403 by direct URL; Dashboard and Profile always stay available.

03

Fine-tune

Rename menu items, hide dashboard widgets and edit-screen metaboxes by ID, and take capabilities away when data must also be closed in REST or AJAX.

04

Shape the experience

Simple client home instead of the dashboard, handover checklist, contextual tips (Pro), the “Ask for help” button, and hidden update or plugin notices.

05

Preview it live

The Client preview frame shows the real admin as the client sees it. Click around inside it before saving.

06

Assign users

Search users by name or email and add them. A user belongs to one profile at a time; people who manage Handoff are never restricted.

05 / Tutorial / Handover

Checklist, branding and support

Handoff → Handover and Handoff → Settings.

01

Write the checklist

Add steps or a task with a link. Built-in steps (log in, change password, first post) complete themselves. Progress is saved per user.

02

Brand the client admin

Agency name, brand color, logo, login URL and admin footer text — used across the client interface and the login page.

03

Set the support email

Settings → Support email. Requests and design change requests are sent there with technical context attached.

04

The client asks for help

The “Ask for help” button sends the site, page, user, role and versions with the message — no back-and-forth to find out what they mean.

06 / Tutorial / Activity

Read and export the change log

Handoff → Activity, for users with the view-log capability.

01

Filter

Filter by user, document or action. Each row shows the time (UTC), element and the value before and after.

02

Keep what you need

Settings → Activity log → Keep entries for (days). 30 by default; Pro raises the ceiling to 3650 days.

03

Export (Pro)

Download the filtered view as CSV (UTF-8 with BOM, opens correctly in Excel).

04

Privacy requests

Log rows of a person are included in Tools → Export / Erase Personal Data.

07 / Tutorial / Content intake (Pro)

Collect content without a login

Handoff → Content intake. Send the client a link; their text and images land exactly where they belong.

01

Create a request

New content request → name it (e.g. Home page content) and enter the client email, used for the invitation and reminders.

02

Add the fields

Each field maps to its destination: an ACF field (best for new projects) or an Elementor element (for sites already built). Set limits: max characters, min image size, max upload size.

03

Send the link

Choose how long the link is valid (14 days by default) and email it. Reminders go out automatically (every 72 hours by default).

04

Review and publish

Open the submitted content, then Publish to site or Send back to client. Or tick “Publish automatically” to skip approval.

05

Manage the link

Email it again, create a new link (the old one stops working) or delete the request. A snapshot is taken before Handoff writes any content.

08 / Settings reference

Every option in Handoff → Settings

Structure lock

Normal — each document follows its own hard-lock setting. Safe mode — every lock only warns and logs (use if a client cannot save).

Site-wide allowed props

JSON map of widget type → content props. Entries replace the default for that widget type. Atomic widgets use their own names, e.g. e-paragraph → paragraph.

Activity log

How many days entries are kept (default 30, up to 3650 with Pro).

Support email

Where support and design-change requests are sent.

Content intake (Pro)

Link validity (14 days), max upload size (5 MB) and reminder interval (72 hours).

Branding

Agency name, brand color (#EB1F27 by default), logo, login URL, admin footer text.

Delete data on uninstall

Off by default. When on, locks, log, content requests and settings are deleted with the plugin.

09 / Architecture

Two enforcement layers

One layer understands Elementor. The other does not have to — it sits under every write to the protected meta keys.

Layer 1

Document save filter

Runs on elementor/document/save/data and on the editor’s ajax return. The incoming tree is walked and compared element by element.

Scope: editor saves, autosaves, template applies.

Layer 2

Meta write backstop

Runs on update_post_metadata, add_post_metadata and delete_post_metadata for the protected keys.

Scope: REST, WP-CLI, cron, other plugins.

10 / Save pipeline

What happens on every save

Incoming write

editor save
REST request
direct meta write

Structure diff

occurrence keys (id, id#2)
type + parent + order
layout props only

Decision

revert structure
keep content edits
write audit entry

Diffing by occurrence key rather than by element id defeats the duplicate-id bypass: two nodes sharing an id no longer look like one. An unparseable incoming tree is rejected; only an unparseable baseline downgrades the lock to a warning, so a corrupt snapshot can never silently unlock a page.

11 / Scope

Reverted vs editable

Reverted

—

adding or removing sections, containers, widgets

—

reordering elements; changing an element type

—

width, padding, margin, gap, alignment

—

column and grid structure

—

page template and layout settings

Editable

—

headings, paragraphs, rich text

—

images, alt text, links

—

button labels and URLs

—

any property on the allow list

—

everything on unlocked documents

12 / Data model

Protected keys and supported formats

A single document walker normalises the three element formats Elementor has shipped, so a lock captured today survives a rebuild with containers or atomic elements.

_elementor_data

element tree — diffed and reverted

_elementor_page_settings

layout keys protected

_elementor_edit_mode

protected against downgrade

elementor_active_kit

site-wide styles watched

legacy section / column

supported

flexbox container

supported

atomic V4 ($$type envelopes)

supported

13 / Capabilities

Who can do what

ston_handoff_manage

Create and release locks, edit profiles, change settings. Administrator by default.

ston_handoff_bypass_lock

Edits pass through untouched — the capability you keep for yourself.

ston_handoff_view_log

Read the change log; rows for documents the user cannot edit stay hidden.

ston_handoff_approve_intake

Review and publish content the client submitted through an intake link.

14 / Logging

Every structural change, with before and after

recorded per entry

time (UTC), user, action, document, element, before, after

retention

7 – 30 days by default, up to 3650 days with the add-on

purge

daily cron, deletes in bounded batches

export

CSV of the filtered view (add-on), UTF-8 with BOM

privacy

WordPress export and erase tools supported

blocked attempts

listed per document on the Locks screen

15 / Extension points

Twelve documented hooks

The add-on is written entirely on top of these; your own snippets can use the same surface, so nothing needs patching.

ston_handoff_enforcement_available

filter — may locks revert changes

ston_handoff_support_context

filter — attach data to a support request

ston_handoff_log_retention_max

filter — raise the retention ceiling

ston_handoff_ignored_post_types

filter — keep a post type out of the log

ston_handoff_admin_pages

filter — add a submenu screen

ston_handoff_admin_notices

filter — register notice codes

ston_handoff_overview_stats

filter — add a stat card

ston_handoff_settings_sections

action — render a settings block

ston_handoff_handover_sections

action — render a handover card

ston_handoff_activity_actions

action — add controls above the log

ston_handoff_pro_url

filter — change the add-on link

ston_handoff_loaded

action — the plugin finished booting

16 / Server footprint

What it creates on the site

{prefix}ston_handoff_locks

baselines and lock settings

{prefix}ston_handoff_log

change log entries

{prefix}ston_handoff_intake

content requests (add-on)

ston_handoff_settings

one option, autoload off

ston_handoff_purge_audit_log

daily cron — log retention

ston_handoff_intake_reminders

hourly cron (add-on)

uploads/ston-handoff-intake-<key>/

private folder, .htaccess + index.php

ston_handoff_tip

hidden post type for in-dashboard tips (add-on)

front-end assets

none — enforcement runs on save

17 / Failure behaviour

What happens when something is missing

add-on inactive

locks fall back to watch mode; nothing is deleted

baseline unparseable

lock downgrades to a warning, save is allowed

incoming tree unparseable

save is rejected, entry written to the log

user has bypass capability

change passes through, still logged

document unlocked

no comparison, no log entry

plugin deactivated

data stays; enforcement stops immediately

uninstall

data removed only if you opted in beforehand

Uninstall order matters: turn on “remove data” in Settings first, then delete the add-on, then the free plugin. The add-on reads that setting from the free plugin’s option, so removing the free plugin first leaves the add-on’s data in place.

18 / Troubleshooting

Common questions

The client cannot save

Switch Settings → Structure lock to Safe mode, then check Recent attempts on the document to see which change was blocked.

A text change was reverted

The prop is not on the allow list. Add it for that widget type in Settings, or per document on its lock screen.

Design changes are kept

Without Pro, locks only watch and log. With Pro, turn on “Hard lock” for the document.

The lock shows a warning

The baseline could not be read. Capture a new baseline; the lock never unlocks silently.

A menu is still visible

Users who can manage Handoff are never restricted. Test with a real client account or in Client preview.

Intake link does not open

The link expired or a new link was created. Create a new link from the request.

19 / Requirements

Runs on the hosting your clients already have.

  • WordPress 6.6+
  • PHP 7.4 – 8.3
  • Elementor 3.x & V4 atomic
  • Multisite ready
  • No front-end assets