wpengine / faustjs

Faust.js™ - The Headless WordPress Framework
https://faustjs.org
Other
1.4k stars 125 forks source link

invalid <Link> with <a> child. Please remove <a> or use <Link legacyBehavior>. #1916

Closed Bowriverstudio closed 1 month ago

Bowriverstudio commented 1 month ago

Description

When using this: example repo

https://github.com/wpengine/faustjs/blob/canary/examples/next/block-support

And a button in the Gutenberg editor I get the message

Error: Invalid with child. Please remove or use . Learn more: https://nextjs.org/docs/messages/invalid-new-link-with-extra-anchor

Steps to reproduce

Use this repo https://github.com/wpengine/faustjs/blob/canary/examples/next/block-support

and this

<!-- wp:cover {"url":"https://cldup.com/Fz-ASbo2s3.jpg","dimRatio":50,"align":"wide"} -->
<div class="wp-block-cover alignwide is-light"><span aria-hidden="true" class="wp-block-cover__background has-background-dim"></span><img class="wp-block-cover__image-background" src="https://cldup.com/Fz-ASbo2s3.jpg" data-object-fit="cover"/><div class="wp-block-cover__inner-container"><!-- wp:paragraph {"align":"center","placeholder":"Write title…","fontSize":"large"} -->
<p class="has-text-align-center has-large-font-size">Of Mountains &amp; Printing Presses</p>
<!-- /wp:paragraph --></div></div>
<!-- /wp:cover -->

<!-- wp:paragraph -->
<p>The goal of this new editor is to make adding rich content to WordPress simple and enjoyable. This whole post is composed of <em>pieces of content</em>—somewhat similar to LEGO bricks—that you can move around and interact with. Move your cursor around and you’ll notice the different blocks light up with outlines and arrows. Press the arrows to reposition blocks quickly, without fearing about losing things in the process of copying and pasting.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>What you are reading now is a <strong>text block</strong> the most basic block of all. The text block has its own controls to be moved freely around the post...</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"right"} -->
<p class="has-text-align-right">... like this one, which is right aligned.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Headings are separate blocks as well, which helps with the outline and organization of your content.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">A Picture is Worth a Thousand Words</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Handling images and media with the utmost care is a primary focus of the new editor. Hopefully, you’ll find aspects of adding captions or going full-width with your pictures much easier and robust than before.</p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center"} -->
<figure class="wp-block-image aligncenter"><img src="https://cldup.com/cXyG__fTLN.jpg" alt="Beautiful landscape"/><figcaption class="wp-element-caption">If your theme supports it, you’ll see the "wide" button on the image toolbar. Give it a try.</figcaption></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Try selecting and removing or editing the caption, now you don’t have to be careful about selecting the image or other text by mistake and ruining the presentation.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">The <em>Inserter</em> Tool</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Imagine everything that WordPress can do is available to you quickly and in the same place on the interface. No need to figure out HTML tags, classes, or remember complicated shortcode syntax. That’s the spirit behind the inserter—the <code>(+)</code> button you’ll see around the editor—which allows you to browse all available content blocks and add them into your post. Plugins and themes are able to register their own, opening up all sort of possibilities for rich editing and publishing.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Go give it a try, you may discover things WordPress can already add into your posts that you didn’t know about. Here’s a short list of what you can currently find there:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li>Text &amp; Headings</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Images &amp; Videos</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Galleries</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Embeds, like YouTube, Tweets, or other WordPress posts.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Layout blocks, like Buttons, Hero Images, Separators, etc.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>And <em>Lists</em> like this one of course :)</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:separator {"opacity":"css"} -->
<hr class="wp-block-separator has-css-opacity"/>
<!-- /wp:separator -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Visual Editing</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>A huge benefit of blocks is that you can edit them in place and manipulate your content directly. Instead of having fields for editing things like the source of a quote, or the text of a button, you can directly change the content. Try editing the following quote:</p>
<!-- /wp:paragraph -->

<!-- wp:quote -->
<blockquote class="wp-block-quote">
<p>The editor will endeavor to create a new page and post building experience that makes writing rich posts effortless, and has “blocks” to make it easy what today might take shortcodes, custom HTML, or “mystery meat” embed discovery.</p>
<footer class="blockquote-footer">Matt Mullenweg, 2017</footer>
</blockquote>
<!-- /wp:quote -->

<!-- wp:paragraph -->
<p>The information corresponding to the source of the quote is a separate text field, similar to captions under images, so the structure of the quote is protected even if you select, modify, or remove the source. It’s always easy to add it back.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Blocks can be anything you need. For instance, you may want to add a subdued quote as part of the composition of your text, or you may prefer to display a giant stylized one. All of these options are available in the inserter.</p>
<!-- /wp:paragraph -->

<!-- wp:gallery {"columns":2,"linkTo":"none"} -->
<figure class="wp-block-gallery has-nested-images columns-2 is-cropped"><!-- wp:image {"linkDestination":"none"} -->
<figure class="wp-block-image"><img src="https://cldup.com/n0g6ME5VKC.jpg" alt=""/><figcaption class="wp-element-caption">Mountains</figcaption></figure>
<!-- /wp:image -->

<!-- wp:image {"linkDestination":"none"} -->
<figure class="wp-block-image"><img src="https://cldup.com/ZjESfxPI3R.jpg" alt=""/><figcaption class="wp-element-caption">Travelling</figcaption></figure>
<!-- /wp:image -->

<!-- wp:image {"linkDestination":"none"} -->
<figure class="wp-block-image"><img src="https://cldup.com/EKNF8xD2UM.jpg" alt=""/><figcaption class="wp-element-caption">Rich Life</figcaption></figure>
<!-- /wp:image --></figure>
<!-- /wp:gallery -->

<!-- wp:paragraph -->
<p>You can change the amount of columns in your galleries by dragging a slider in the block inspector in the sidebar.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Media Rich</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>If you combine the new <strong>wide</strong> and <strong>full-wide</strong> alignments with galleries, you can create a very media rich layout, very quickly:</p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"full"} -->
<figure class="wp-block-image alignfull"><img src="https://cldup.com/8lhI-gKnI2.jpg" alt="Accessibility is important — don’t forget image alt attribute"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Sure, the full-wide image can be pretty big. But sometimes the image is worth it.</p>
<!-- /wp:paragraph -->

<!-- wp:gallery {"linkTo":"none","align":"wide","className":"alignwide"} -->
<figure class="wp-block-gallery alignwide has-nested-images columns-default is-cropped"><!-- wp:image {"linkDestination":"none"} -->
<figure class="wp-block-image"><img src="https://cldup.com/_rSwtEeDGD.jpg" alt=""/></figure>
<!-- /wp:image -->

<!-- wp:image {"linkDestination":"none"} -->
<figure class="wp-block-image"><img src="https://cldup.com/L-cC3qX2DN.jpg" alt=""/></figure>
<!-- /wp:image --></figure>
<!-- /wp:gallery -->

<!-- wp:paragraph -->
<p>The above is a gallery with just two images. It’s an easier way to create visually appealing layouts, without having to deal with floats. You can also easily convert the gallery back to individual images again, by using the block switcher.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Any block can opt into these alignments. The embed block has them also, and is responsive out of the box:</p>
<!-- /wp:paragraph -->

<!-- wp:embed {"url":"https://vimeo.com/22439234","type":"video","providerNameSlug":"vimeo","responsive":true,"align":"wide","className":"wp-has-aspect-ratio wp-embed-aspect-16-9"} -->
<figure class="wp-block-embed alignwide is-type-video is-provider-vimeo wp-block-embed-vimeo wp-has-aspect-ratio wp-embed-aspect-16-9"><div class="wp-block-embed__wrapper">
https://vimeo.com/22439234
</div></figure>
<!-- /wp:embed -->

<!-- wp:paragraph -->
<p>You can build any block you like, static or dynamic, decorative or plain. Here’s a pullquote block:</p>
<!-- /wp:paragraph -->

<!-- wp:pullquote -->
<figure class="wp-block-pullquote"><blockquote><p>Code is Poetry</p><cite>The WordPress community</cite></blockquote></figure>
<!-- /wp:pullquote -->

<!-- wp:buttons -->
<div class="wp-block-buttons"><!-- wp:button -->
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button" href="https://brudco.test/testing">Testing</a></div>
<!-- /wp:button --></div>
<!-- /wp:buttons -->

<!-- wp:paragraph {"align":"center"} -->
<p class="has-text-align-center"><em> If you want to learn more about how to build additional blocks, or if you are interested in helping with the project, head over to the <a href="%s">GitHub repository</a>. </em></p>
<!-- /wp:paragraph -->

<!-- wp:separator {"opacity":"css"} -->
<hr class="wp-block-separator has-css-opacity"/>
<!-- /wp:separator -->

<!-- wp:paragraph {"align":"center"} -->
<p class="has-text-align-center">Thanks for testing Gutenberg!</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"align":"center"} -->
<p class="has-text-align-center"><img class="emoji" draggable="false" src="https://s.w.org/images/core/emoji/2.3/svg/1f44b.svg" alt="👋"></p>
<!-- /wp:paragraph -->

Additional context

"@faustwp/blocks": "4.0.0", "@faustwp/cli": "^3.0.2", "@faustwp/core": "^3.0.1",

@faustwp/core Version

3.0.1"

@faustwp/cli Version

3.0.2

FaustWP Plugin Version

1.3.1

WordPress Version

6.5.4

Additional environment details

No response

Please confirm that you have searched existing issues in the repo.

theodesp commented 1 month ago

Hey @Bowriverstudio I suspect the issue comes from the buttons block.

<!-- wp:buttons -->
<div class="wp-block-buttons"><!-- wp:button -->
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button" href="https://brudco.test/testing">Testing</a></div>
<!-- /wp:button --></div>
<!-- /wp:buttons -->

The code for adding the Next.js link is here

https://github.com/wpengine/faustjs/blob/canary/packages/blocks/src/blocks/CoreButton.tsx#L38-L39

However I wasn't able to reproduce in the block-support example. I was able to add a local link but the only thing I got was a warning:

next-dev.js:28 Warning: Prop `href` did not match. Server: "http://localhost:3000/sample-page/" Client: "http://localhost:3000/sample-page"
Bowriverstudio commented 1 month ago

@theodesp What version of next js did you use? I should have mentioned I am using 14.x image

https://github.com/wpengine/faustjs/blob/canary/packages/blocks/src/blocks/CoreButton.tsx

has this code

<Link href={attributes?.url}>
          <a
            target={linkTarget}
            className={attributes?.linkClassName}
            rel={attributes?.rel}
            style={style}>
            <span>{attributes?.text}</span>
          </a>
        </Link>
    This code would work in 13.x 
theodesp commented 1 month ago

Hello @Bowriverstudio Im using the block-support example which is "next": "^14.2.3" I literary copy the link inside the template

    <div className="is-layout-constrained">
      <h1>{title}</h1>
      <WordPressBlocksViewer blocks={blockList} />
      <Link href={"/hello"}>
        <a>
          <span>"Hello"</span>
        </a>
      </Link>
    </div>

And this does not trigger any issues whatsoever. It also builds without an error.

I'm not sure if there a configuration value that makes Next.js stricter.

Bowriverstudio commented 1 month ago

@theodesp Thank you for looking into this.

This works for me:

 <Link href={"/hello"} legacyBehavior>
          <a>
            <span>"Hello"</span>
          </a>
        </Link>

This does not:

 <Link href={"/hello"}>
          <a>
            <span>"Hello"</span>
          </a>
        </Link>

Vercel - does talk about this issue: https://nextjs.org/docs/messages/invalid-new-link-with-extra-anchor

I have made my own block which gets around this issue (but it does not use all the features you guys have added).

Would it be possible to have two versions of the block -- so I could import either one depending on my next js config?

theodesp commented 1 month ago

Hey @Bowriverstudio. Thank you. I don't think we should add two versions of the same block just for this. It will be a maintenance hell. What we could do is at some point, add the legacyBehavior property only when we drop support for Next.js < 14. This probably is technical debt that we have to manage, unless there is a better way.

Bowriverstudio commented 1 month ago

@theodesp Thanks.