0

I'm working in a plugin for blocks with the npx @wordpress/create-block structure. In the edit() function I've imported Vime library to add a video. This library supports React.

Vime Youtube component

So, after add the library to the plugin node_modules, my edit file is:

import { Player, Youtube } from "@vime/react";

export default function Edit({ className, attributes, setAttributes }) {
    return (
        <div {...useBlockProps()}>
            <Player controls>
                <Youtube videoId="DyTCOwB0DVw" />
            </Player>
        </div>
    );
}

It works. I can insert the block in the editor and the video player is rendered:

enter image description here

After that, I try to do the same in the save file:

import { useBlockProps } from "@wordpress/block-editor";
import { Player, Youtube } from "@vime/react";

export default function save({ attributes }) {
    return (
        <div {...useBlockProps.save()}>
            <Player controls>
                <Youtube videoId="DyTCOwB0DVw" />
            </Player>
        </div>
    );
}

But this doesn't work. The block is not rendered in the front end and, when I add a block in the editor, the editor show me a blank page. Am I calling the library incorrectly or could it be a bug in the library or maybe some incompatibility with my theme? I appreciate any hint or help.

1 Answer 1

3

So the important thing to understand here is that while the block editor is React based, and can use React components, the data it saves is purely HTML. So your block will simply save the HTML output of its save() function to the post's content in the database. When that content is output on the front end this HTML is what will be printed, without the involvement of any of your block's code.

What this means is that you need a save method that prints some placeholder HTML for the block, and a separate script that takes the placeholder and converts it into the live element that you want.

So your save method should look something like:

import { useBlockProps } from "@wordpress/block-editor";
import { Player, Youtube } from "@vime/react";

export default function save({ attributes }) {
    return (
        <div {...useBlockProps.save()}>
            <div className="vime" data-video-id="DyTCOwB0DVw"></div>
        </div>
    );
}

Then you would need a separate script that looks for .vime elements and takes the data-video-id and does whatever the Vime library requires to turn that into a video player.

Looking at the Vime documentation, the best approach would likely be to just use the HTML from their HTML example in your save method:

import { useBlockProps } from "@wordpress/block-editor";

export default function save({ attributes }) {
    return (
        <div {...useBlockProps.save()}>
            <vm-player controls>
                <vm-youtube video-id="DyTCOwB0DVw"></vm-youtube>
            </vm-player>
        </div>
    );
}

Then, on the front end, you would just need to load the appropriate scripts and stylesheets as per their HTML Example.

2
  • Thank you very much for this explanation. That save() is not React based is a core concept that I completely ignored. The next steps are clear now.
    – aitor
    Jul 25, 2022 at 13:26
  • 1
    No problem. To be clear, you can use React in the save method, but it's ultimately only going to save the rendered HTML. So it's perfectly ok to use React as a means for generating that HTML, it just won't result in the React code itself running on the front end. Jul 25, 2022 at 13:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.