Elementor Template Blank After Saving? A Hostinger Fix

Elementor Template Blank After Saving? A Hostinger Fix

An Elementor template looks right when you import it. You make a change, save, and open the preview. Nothing. Reload the editor, and the layout has disappeared there too.

We investigated this during a WordPress build using Elementor and Elementor Pro on Hostinger. Some imported templates failed; other pages saved normally. The cause was a content-dependent corruption of saved layout data in the preview-domain handling code.

If your Elementor template is blank after saving, this case offers a specific diagnosis to check—not a universal patch for every blank page.


Quick answer: what fixed this installation?

 

Hostinger’s preview-domain MU-plugin passed an already-unslashed metadata value back through WordPress’s metadata API without restoring the required escaping. The second unslashing pass damaged the JSON that Elementor needed to reconstruct the layout.

In the inspected filter_meta_save() implementation, wrapping $cleaned in wp_slash() in both the add_metadata() and update_metadata() calls resolved the reproduced failure. The full Contact template then survived import, editing, saving and reloading.

Check for the same faulty calls and evidence before applying this correction. A blank preview by itself does not establish this diagnosis.


Why only some Elementor templates disappeared

 

The production domain had not yet been connected, so development used a temporary Hostinger domain. That was relevant to the investigation, but it did not explain the failure on its own.

A Contact template gave us a repeatable example. It contained ordinary text, links and a form. The import initially looked successful, yet saving could leave both the preview and the reopened editor empty. Simple pages continued to work.

We also saw the problem while testing an atomic replacement form. Changing the form type alone did not establish a solution. There was no basis for declaring that a particular widget was inherently broken.

The important distinction was the saved content. The preview-domain handler checked whether metadata contained the current preview-domain string before attempting replacement. Content that matched could enter the faulty rewriting path; content that did not match could avoid it. That explained why a successful save on a simple page was not enough to clear the installation.


How we narrowed down the failure

 

We inspected Elementor’s stored layout data, rather than judging the issue only from the browser. Elementor stores layout JSON in the _elementor_data post-meta field. Earlier imported revisions contained valid JSON; failed saved revisions contained invalid JSON.

Escaping had disappeared throughout the affected layout. Quotes inside HTML attributes and form settings were no longer escaped correctly, and some Unicode escape sequences were damaged. This was evidence of malformed stored content, not evidence that the database row had been deleted.

We also checked several alternative explanations:

  • The original Contact layout had no duplicate element IDs.
  • WordPress core and Elementor core passed checksum verification.
  • The custom theme’s inspected PHP files contained no handler rewriting Elementor layout data.
  • The active custom snippets handled image uploads, not Elementor saves.

These checks narrowed the investigation; they were not a claim that every possible interaction had been excluded. A separate save test showed domain replacement affecting an email address. That was a useful clue towards the rewriting layer, not proof by itself.

Repeated cache clearing would not reconstruct JSON whose escaping had already been removed in storage. Nor did our evidence establish memory limits or PHP versions as the cause. We needed to follow the write path.


The technical cause: JSON met a second unslashing pass

 

Escaped JSON is different from the HTML it contains

Consider this small, valid JSON example:

{"text":"<a href=\"https://example.com\">Contact</a>"}

The backslashes protect the quotes around the HTML attribute inside the JSON string. After JSON decoding, the represented HTML is:

<a href="https://example.com">Contact</a>

If those protective backslashes disappear before JSON decoding, the stored value becomes:

{"text":"<a href="https://example.com">Contact</a>"}

This last example is deliberately invalid JSON: the attribute quotes interrupt the surrounding string. Valid HTML inside a field does not mean that the JSON holding it is valid.


Where the extra processing happened

 

The WordPress source for update_metadata() shows that it unslashes the incoming value before calling the metadata filter. If a handler then calls the metadata API again, that nested call processes the value again.

In our inspected preview-domain handler, the nested call received $cleaned without the slashing expected by the API. A re-entry guard stopped the plugin’s rewriting logic from recurring indefinitely, but it did not stop WordPress from performing the second unslashing operation.

The add_metadata() source likewise unslashes its incoming metadata value before filtering it. Both branches therefore needed attention in this implementation.

WordPress also documents the risk of storing JSON with escaped quotes in its post-meta character escaping guidance. Its wp_slash() reference describes preparing values for APIs that expect slashed input. This is an API-boundary correction, not an instruction to add arbitrary backslashes to exported Elementor files.


The exact two-line correction

The file we inspected was:

wp-content/mu-plugins/hostinger-preview-domain.php

Its header identified Hostinger Preview Domain, version 1.4.0. That identifies the source on the investigated installation. It does not establish that every installation of that version is affected, or that the latest public release contains the same code.

Must-use plugins load automatically and appear separately from ordinary plugins in WordPress. They do not have the usual deactivate toggle. A normal plugin-list check can therefore miss a hosting integration involved in saving data.


Add operation

Original call:

$result = add_metadata( $meta_type, $object_id, $meta_key, $cleaned, (bool) $extra );

Corrected call:

$result = add_metadata( $meta_type, $object_id, $meta_key, wp_slash( $cleaned ), (bool) $extra );



Update operation

Original call:

$result = update_metadata( $meta_type, $object_id, $meta_key, $cleaned, $extra );

Corrected call:

$result = update_metadata( $meta_type, $object_id, $meta_key, wp_slash( $cleaned ), $extra );

Within the existing guard, the corrected block was:

self::$meta_filter_in_progress[ $meta_type ] = true;
try {
    if ( $is_add ) {
        $result = add_metadata( $meta_type, $object_id, $meta_key, wp_slash( $cleaned ), (bool) $extra );
    } else {
        $result = update_metadata( $meta_type, $object_id, $meta_key, wp_slash( $cleaned ), $extra );
    }
} finally {
    self::$meta_filter_in_progress[ $meta_type ] = false;
}

The guard and finally block remain in place. The change prepares the cleaned value for the nested metadata write; it does not replace the plugin’s domain-rewriting logic.


How to apply this safely

 

Use your hosting file manager or authorised development access. Keep a copy of the original file and test on staging before changing a production installation.

  1. Locate filter_meta_save() in the identified MU-plugin.
  2. Verify that your implementation contains the same two faulty calls and the same relevant processing sequence.
  3. Change only the identified arguments to use wp_slash( $cleaned ).
  4. Check the edited PHP syntax and confirm that the saved file contains the intended changes.
  5. Run the full content-based verification below.

Use matching code, not line numbers: file layouts vary between releases. If your implementation differs, investigate it before adapting the patch. Editing Elementor core, disabling security or shutting down unrelated plugins is not part of this correction.


Verify with the full template that previously failed

 

A test containing only a heading can pass while the original failure remains. Preserve the content that exercises the domain-rewriting path.

  1. Create a temporary test page.
  2. Import a known-good copy of the previously failing full template.
  3. Keep its form and relevant links intact.
  4. Make a visible change and save.
  5. Reload the editor and check that the complete layout remains.
  6. Open the preview and confirm that the changed content appears.
  7. Repeat a meaningful edit-and-save cycle.
  8. Check the resulting email addresses and link destinations, as well as JSON validity.

After our correction, the source file was checked and the user tested the full Contact template. The previously failing workflow worked, and the user confirmed that the content remained.

That supports the diagnosis and confirms the repair for the reproduced failure on this installation. The repeated cycle and final address checks above are recommended validation steps, not additional results we claim to have already proved. Valid JSON alone does not guarantee correct domain rewriting.


Recover pages that were already affected

 

Preventing corruption and recovering content are separate jobs. Correcting future writes does not restore escaping already lost from stored JSON.

Restore a known-good revision or reimport the original valid template, then repeat the save-and-reload test. Keep the damaged data available if careful recovery is necessary, rather than repeatedly saving over your only remaining copy.

Avoid speculative global search-and-replace operations on the JSON. Quotes can be structural or part of a value; indiscriminately adding escapes may create different damage. Where no valid revision or export remains, recovery needs inspection of the actual data.


Will the repair survive an update?

 

A manual change to a hosting-managed MU-plugin may be overwritten. Report the defect to Hostinger with the relevant code and a minimal, anonymised reproduction, and use a vendor-maintained correction when available.

We have not established vendor acknowledgement, a released vendor fix or survival of this patch through an update. After hosting-plugin changes, rerun the previously failing template test. Connecting the production domain may change the rewriting context, but it is not proof that the underlying implementation has been permanently corrected.



Frequently asked questions

1. Why is my Elementor template blank after saving?

In this case, saving corrupted the layout JSON through an extra unslashing pass. Other blank-page failures can have different causes. Compare a known-good layout with the failed saved data before choosing a fix.

2. Does an email address cause Elementor content to disappear?

Not by itself. The trigger depended on matching content within an active domain-rewriting context. An altered email address was a clue in our investigation, not evidence that all email fields break Elementor.

3. Should I edit the imported JSON template?

Not to apply this fix. The correction belongs in the verified metadata-writing calls. Start recovery with a valid export rather than adding backslashes throughout a template file.

4. Will clearing the cache restore the missing layout?

It will not repair malformed JSON already stored in the database. First determine whether the content is damaged or whether you have a separate display or caching problem.

5. Does this affect every Hostinger Elementor website?

We have no evidence for that claim. This case concerns the inspected preview-domain implementation and reproduced content-dependent failure on one installation.



Inspect the saved data before rebuilding the design

The useful lesson was to reproduce the failure with the original content and inspect what actually survived the save. Rebuilding the Contact page or swapping its form could have hidden the symptom without correcting the write path.If you are facing a similar WordPress issue, contact byKlash for WordPress troubleshooting.

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top