nuxt / bridge

🌉 Experience Nuxt 3 features on existing Nuxt 2 projects
MIT License
273 stars 29 forks source link

`<title>` element of SVG is treated as `<Title>` component from Nuxt when `meta: true` #1007

Open yckimura opened 11 months ago

yckimura commented 11 months ago

Environment


Reproduction

https://stackblitz.com/edit/nuxt-starter-v8fpj4

Describe the bug

<title> element of SVG is treated as <Title> component from Nuxt Bridge when meta: true. It only appears in production build (nuxi build).

components/SvgCircle.vue:

<template>
  <svg width="100" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
    <slot />
    <circle cx="100" cy="100" r="50" />
  </svg>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({});
</script>

pages/index.vue:

<template>
  <div>
    <SvgCircle>
      <title>circle</title>
    </SvgCircle>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import SvgCircle from '~/components/SvgCircle.vue';

export default defineComponent({
  components: {
    SvgCircle,
  },
});
</script>

nuxt.config.ts:

import { defineNuxtConfig } from '@nuxt/bridge';

export default defineNuxtConfig({
  bridge: {
    meta: true,
  },
});

Output:

<html>
  <head>
    <title>circle</title>
...
  </head>
  <body>
    <div id="__nuxt">
      <!---->
      <div id="__layout">
        <div>
          <svg width="100" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
            <!---->
            <circle cx="100" cy="100" r="50"></circle>
          </svg>
        </div>
      </div>
    </div>
...
  </body>
</html>

Additional context

No response

Logs

No response

yckimura commented 11 months ago

To workaround this, unset the Title component on components:extend hook.

import { defineNuxtConfig } from '@nuxt/bridge';
import { defineNuxtModule } from '@nuxt/kit';

export default defineNuxtConfig({
  bridge: {
    meta: true,
  },
  modules: [
    defineNuxtModule((options, nuxt) => {
      nuxt.hook('components:extend', (components) => {
        const foundIndex = components.findIndex(
          (x) => x.pascalName === 'Title'
        );
        if (foundIndex !== -1) {
          components.splice(foundIndex, 1);
        }
      });
    }),
  ],
});