2

Just starting to play with Gutenberg block development, and I am building a very simple button (yes I know buttons are already included, but this block will have lots of settings and classes not included in the core block).

Seem's pretty strait forward, but when I save the block and reload, I get a validation error and the "This block appears to have been modified externally" message.

registerBlockType('franklin/button', {
    title: 'Button',
    keywords: ['button' ],
    icon: 'admin-links',
    category: 'layout',
    attributes: {
        text: {
            source: 'text',
            selector: '.button-text'
        },
    },

    edit({attributes, setAttributes }) {

        return (
            <div class="guttenberg-usa-button">
                <button class="usa-button">
                    <PlainText
                      onChange={ content => setAttributes({ text: content }) }
                      value={ attributes.text }
                      placeholder="Your button text"
                      className="button-text"
                    /> 
                </button>
            </div>
        );
    },

    save({attributes}) {
        return (
            <button class="usa-button">
                { attributes.text }
            </button>
        );
    } 

});

So in the editor, I'll add my block, modify the (button) text, save, and reload where I get the This block appears to have been modified externally" message.

Console shows the following error

Expected:

<button class="usa-button" class="wp-block-franklin-button"></button>

Actual:

<button class="usa-button" class="wp-block-franklin-button">testest</button>

I must be missing some fundamental concept or something, but I thought the save() function determines what gets displayed on the frontend which btw, looks as expected.

2
  • 1
    While this isn't off topic, your chances of getting an answer if you create an issue on the GitHub repo for Gutenberg are higher, I'd say by 100x
    – Tom J Nowell
    Jun 28 '18 at 17:38
  • 2
    In your attributes you have .button-text as the selector for the text attribute, but you don't have it in the saved output. Try adding and element with .button-text class to the saved output. Jun 29 '18 at 1:30
0

You are getting this error because your edit and save function output doesn't match.

 save({attributes}) {
    return (
        <button class="usa-button">
            { attributes.text }
        </button>
    );
} 

precisely, { attributes.text } is the save function is not being called or used in edit function. Either add attributes.text in edit function or remove that from save function. Something like this should work -

 <button class="usa-button">
                    <PlainText
                      onChange={ content => setAttributes({ text: content }) }
                      value={ attributes.text }
                      placeholder="Your button text"
                      className="button-text"
                    /> { attributes.text }
                </button>

Notice attributes.text is also outputting same text in the edit function just like save function.

0

This is because your attribute is using the HTML to get its value, and the selector is .button-text, but there is nothing that matches that selector in the saved output.

    save({attributes}) {
        return (
            <button class="usa-button">
                { attributes.text }
            </button>
        );
    } 

Notice that button-text is nowhere to be found, therefore its value is empty. This contradicts the edit component which does contain such a class.

Either change the attribute to not use HTML/text as the source, or ensure that the selector matches something that contains the text in the saved output.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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