withastro / astro

The web framework for content-driven websites. ⭐️ Star to support our work!
https://astro.build
Other
46.35k stars 2.45k forks source link

Parent <a> tag recursivly injected into subtags of its dynamic loaded component child #11647

Closed T1xx1 closed 2 months ago

T1xx1 commented 2 months ago

Astro Info

Astro                    v4.13.1
Node                     v22.2.0
System                   Windows (x64)
Package Manager          pnpm
Output                   static
Adapter                  none
Integrations             @astrojs/react
                         @astrojs/svelte
                         @astrojs/tailwind

If this issue only occurs in one browser, which browser is a problem?

No response

Describe the Bug

I'm loading a list of dynamic component previews with import() and showing them with a map() inside a <a> tag that redirects to the component page.

<div class="flex flex-wrap gap-5 justify-center">
         {
            componentsCollection.map(async (componentEntry) => {
               const Component = (
                  await import(
                     `../content/components/${componentEntry.id}/index.astro`
                  )
               ).default;

               return (
                  <a
                     href={`./${componentEntry.id}`}
                     class="card-btn pt-4 w-full md:w-[49%] space-y-3"
                  >
                     <h3 class="h3 text-center">{componentEntry.data.title}</h3>

                     <Component />
                  </a>
               );
            })
         }
      </div>

One component wasn't loading correctly outside of the <a> borders.

image

I looked into the HTML with dev tools and I find out that something strange is happening.

The <Component /> is not loading inside the <a> tag and the same <a> is being loaded inside the component's subtags recursively.

image Look for <a href="./createaccount">...

What's the expected result?

Load correctly.

Workaround: use something else than <a>

<div class="flex flex-wrap gap-5 justify-center">
         {
            componentsCollection.map(async (componentEntry) => {
               const Component = (
                  await import(
                     `../content/components/${componentEntry.id}/index.astro`
                  )
               ).default;

               return (
                  <div class="card pt-3 w-full md:w-[49%] space-y-3">
                     <h3 class="h3 text-center">
                        <a href={`./${componentEntry.id}`} class="link">
                           {componentEntry.data.title}
                        </a>
                     </h3>

                     <Component />
                  </div>
               );
            })
         }
      </div>

The bug only happens when the parent is a <a>.

Codebase Commit before I "fixed" this.

Link to Minimal Reproducible Example

https://stackblitz.com/edit/withastro-astro-txw7ef?file=src%2Fpages%2Findex.astro&view=editor

Participation

T1xx1 commented 2 months ago

I've set the <a> border red in the stackbliz preview so it's clearer

Princesseuh commented 2 months ago

You cannot have a tags inside other a tags in HTML. The same problem happen in normal HTML, outside of Astro.

Transparent, but there must be no interactive content descendant, a element descendant, or descendant with the tabindex attribute specified.

For instance, this code in a .html file:

<a href="a-link">
    <h3>Title</h3>
    <div>
        <div>
            <div>Hello</div>
            <a href="some-other-link">Another link</a>
        </div>
    </div>
</a>

result in this HTML in the browser (ignore the formatting, just ran it through Prettier so it's easier to read), with duplicated links everywhere:

<a href="a-link">
  <h3>Title</h3>
</a>
<div>
  <a href="a-link"></a>
  <div>
    <a href="a-link">
      <div>Hello</div>
    </a>
    <a href="some-other-link">Another link</a>
  </div>
</div>