Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Yoast SEO Removes Blocks with Block Recovery on Save #21947

Open
ToinePK opened this issue Jan 3, 2025 · 7 comments
Open

Yoast SEO Removes Blocks with Block Recovery on Save #21947

ToinePK opened this issue Jan 3, 2025 · 7 comments

Comments

@ToinePK
Copy link

ToinePK commented Jan 3, 2025

When editing a page in the WordPress block editor, any block with a "block recovery" status (e.g., due to changes in its save method) will be removed upon saving the page if the Yoast SEO plugin is active. This issue occurs when the block is used as an inner block inside another block (e.g., core/group). Instead of preserving the block, Yoast's getBlocks function inadvertently causes its removal.

Steps to Reproduce:

  1. Install and activate the Yoast SEO plugin.
  2. Create a custom block and make changes to its save method to trigger a "block recovery" state.
  3. Add the custom block as an inner block inside a parent block (e.g., core/group).
  4. Save the page.

Expected Behavior:
The block editor should save all blocks, including those in a "block recovery" state. The Yoast SEO plugin should only collect data for analysis and should not modify or remove blocks.

Actual Behavior:
Any block with a "block recovery" state is removed from the content during the save process.

Potential Cause:
The issue appears to stem from the getBlocks function in Yoast SEO's collectAnalysisData.js. The function likely processes blocks in a destructive manner, removing blocks that are in a recovery state instead of collecting their data non-invasively.

Environment:
Yoast SEO Version: 23.3+

Suggested Solution:
The getBlocks function should be updated to operate in a non-destructive manner. Specifically, it should only collect analysis data from blocks and leave their structure intact. Blocks in a recovery state must not be removed during the save process.

Additional Notes:
This issue affects blocks with "block recovery" status nested inside other blocks, such as a core/group block. The removal of these blocks can lead to significant data loss and disruption in workflows.

@peter-otten
Copy link

peter-otten commented Jan 9, 2025

What the fix can be is to deepclone blocks you are using so the reference gets deleted.
Now the innerblocks that gets written with the valid blocks is based on a reference to the main block of the editor.
Something like https://developer.mozilla.org/en-US/docs/Glossary/Deep_copy or https://developer.mozilla.org/en-US/docs/Web/API/Window/structuredClone might help.

export const mapGutenbergBlocks = ( blocks ) => {
	blocks = structuredClone( blocks );
	blocks = blocks.filter( block => block.isValid );
	blocks = blocks.map( block => {
		const serializedBlock = serialize( [ block ], { isInnerBlocks: false } );
		block.blockLength = serializedBlock && serializedBlock.length;
		if ( block.innerBlocks ) {
			block.innerBlocks = mapGutenbergBlocks( block.innerBlocks );
		}
		return block;
	} );
	return blocks;
};

Something like this helps:
blocks = structuredClone( blocks );

@josevarghese
Copy link
Contributor

Hi @ToinePK

Thank you for creating the issue and using the Yoast SEO plugin. Could you please share a video or screencast demonstrating the issue?

Additionally, could you provide more details about why the "block recovery" message appears in the editor? Does another block plugin cause it, or could it be related to an incorrect method used to trigger it?

We look forward to hearing from you and are happy to help you.

@ToinePK
Copy link
Author

ToinePK commented Jan 13, 2025

Hey @josevarghese ,

I've created a screencast of the problem. You can find it here.

The message about the block recovery appears when the saved content differs from what is expected to be returned. This issue happens when block deprecation isn't done or done properly when changing block content.

We maintain our own plugins and ecosystem within Wordpress for all our customers. It sometimes happens "block recovery" is triggered with our plugins/blocks, third party plugins/blocks and in the past a few cases of core blocks. However block recovery is a problem out of reach of Yoast, the Yoast' Analysis Data function should operate in a non-destructive manner. We've had customers lose a lot of content/data due to this problem.

@peter-otten was right on the money with his suggestion. If you de-reference / copy the blocks array, the problem will be fixed.

@josevarghese
Copy link
Contributor

Hi @ToinePK

Thank you for taking the time to share more details along with the screencast. I have informed our development team to investigate this further. I will let you know as soon as I get more information. Kindly please keep the video available without deleting it.

@josevarghese
Copy link
Contributor

Internal Slack conversation: https://yoast.slack.com/archives/C01NCRHHN30/p1736857817783019

@ToinePK
Copy link
Author

ToinePK commented Jan 14, 2025

Hey @josevarghese , thank you. We will keep the video up.

@mhkuu
Copy link
Contributor

mhkuu commented Jan 24, 2025

Thanks for the report 🙏

The specific code referenced above was introduced in #21520, it would be best to refactor that blockLength bit and return to just filtering the valid blocks at this point. As a stopgap, the proposed solution also works, but it's preferable to fix this properly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants