vue.jsionic-frameworksvgnuxt.js

Why does my icon sometimes fail to display?


So in my code, I use an icon in the following way:

<template>
  <IconTeamJournal class="w-4 h-4" />
</template>

<script setup lang="ts">
import IconTeamJournal from '~/components/icon/IconTeamJournal.vue';
</script>

The icon is as follows:

<template>
    <svg
        width="844"
        height="844"
        viewBox="0 0 844 844"
        fill="none"
        xmlns="http://www.w3.org/2000/svg"
    >
        <path
            d="M843.995 430.44H0.00476076C0.690863 465.408 5.63102 499.333 14.3292 531.72H829.671C838.369 499.333 843.309 465.408 843.995 430.44Z"
            fill="url(#paint0_linear_29_3)"
        />
        <path
            d="M824.755 548.6H19.2449C28.5687 578.28 41.0839 606.548 56.3886 633H787.612C802.916 606.548 815.431 578.28 824.755 548.6Z"
            fill="url(#paint1_linear_29_3)"
        />
        <path
            d="M777.31 649.88H66.6904C82.3345 674.213 100.411 696.834 120.576 717.4H723.424C743.589 696.834 761.666 674.213 777.31 649.88Z"
            fill="url(#paint2_linear_29_3)"
        />
        <path
            d="M705.897 734.28H138.103C163.265 757.16 191.203 777.042 221.353 793.36H622.647C652.797 777.042 680.735 757.16 705.897 734.28Z"
            fill="url(#paint3_linear_29_3)"
        />
        <path
            d="M587.697 810.24H256.303C307.175 831.971 363.182 844 422 844C480.818 844 536.826 831.971 587.697 810.24Z"
            fill="url(#paint4_linear_29_3)"
        />
        <path
            d="M843.995 413.56H0.00476074C0.90267 367.797 9.0866 323.82 23.4446 282.74H820.555C834.914 323.82 843.097 367.797 843.995 413.56Z"
            fill="url(#paint5_linear_29_3)"
        />
        <path
            d="M814.245 265.86C752.16 110.089 599.939 0 422 0C244.061 0 91.8397 110.089 29.7551 265.86H814.245Z"
            fill="url(#paint6_linear_29_3)"
        />
        <defs>
            <linearGradient
                id="paint0_linear_29_3"
                x1="422"
                y1="0"
                x2="422"
                y2="844"
                gradientUnits="userSpaceOnUse"
            >
                <stop stop-color="#C24CFC" />
                <stop
                    offset="1"
                    stop-color="#FFD500"
                />
            </linearGradient>
            <linearGradient
                id="paint1_linear_29_3"
                x1="422"
                y1="0"
                x2="422"
                y2="844"
                gradientUnits="userSpaceOnUse"
            >
                <stop stop-color="#C24CFC" />
                <stop
                    offset="1"
                    stop-color="#FFD500"
                />
            </linearGradient>
            <linearGradient
                id="paint2_linear_29_3"
                x1="422"
                y1="0"
                x2="422"
                y2="844"
                gradientUnits="userSpaceOnUse"
            >
                <stop stop-color="#C24CFC" />
                <stop
                    offset="1"
                    stop-color="#FFD500"
                />
            </linearGradient>
            <linearGradient
                id="paint3_linear_29_3"
                x1="422"
                y1="0"
                x2="422"
                y2="844"
                gradientUnits="userSpaceOnUse"
            >
                <stop stop-color="#C24CFC" />
                <stop
                    offset="1"
                    stop-color="#FFD500"
                />
            </linearGradient>
            <linearGradient
                id="paint4_linear_29_3"
                x1="422"
                y1="0"
                x2="422"
                y2="844"
                gradientUnits="userSpaceOnUse"
            >
                <stop stop-color="#C24CFC" />
                <stop
                    offset="1"
                    stop-color="#FFD500"
                />
            </linearGradient>
            <linearGradient
                id="paint5_linear_29_3"
                x1="422"
                y1="0"
                x2="422"
                y2="844"
                gradientUnits="userSpaceOnUse"
            >
                <stop stop-color="#C24CFC" />
                <stop
                    offset="1"
                    stop-color="#FFD500"
                />
            </linearGradient>
            <linearGradient
                id="paint6_linear_29_3"
                x1="422"
                y1="0"
                x2="422"
                y2="844"
                gradientUnits="userSpaceOnUse"
            >
                <stop stop-color="#C24CFC" />
                <stop
                    offset="1"
                    stop-color="#FFD500"
                />
            </linearGradient>
        </defs>
    </svg>
</template>

This is how it looks when the icon is shown:

icon-showed

This is what it looks like when the icon is not being shown:

icon-not-showed

I use Vue, Nuxt, and Ionic, and sometimes the icon would disappear after refreshing the page multiple times or navigating from another page. The behavior was random, and I couldn’t figure out why. However, I found a fix and want to share it.

I fixed the problem by adding the key to the path and the linearGradient as follows:

<template>
    <svg
        width="844"
        height="844"
        viewBox="0 0 844 844"
        fill="none"
        xmlns="http://www.w3.org/2000/svg"
    >
        <path
            :key="`path0-${key}`"
            d="M843.995 430.44H0.00476076C0.690863 465.408 5.63102 499.333 14.3292 531.72H829.671C838.369 499.333 843.309 465.408 843.995 430.44Z"
            :fill="`url(#paint0_linear_${key})`"
        />
        <path
            :key="`path1-${key}`"
            d="M824.755 548.6H19.2449C28.5687 578.28 41.0839 606.548 56.3886 633H787.612C802.916 606.548 815.431 578.28 824.755 548.6Z"
            :fill="`url(#paint1_linear_${key})`"
        />
        <path
            :key="`path2-${key}`"
            d="M777.31 649.88H66.6904C82.3345 674.213 100.411 696.834 120.576 717.4H723.424C743.589 696.834 761.666 674.213 777.31 649.88Z"
            :fill="`url(#paint2_linear_${key})`"
        />
        <path
            :key="`path3-${key}`"
            d="M705.897 734.28H138.103C163.265 757.16 191.203 777.042 221.353 793.36H622.647C652.797 777.042 680.735 757.16 705.897 734.28Z"
            :fill="`url(#paint3_linear_${key})`"
        />
        <path
            :key="`path4-${key}`"
            d="M587.697 810.24H256.303C307.175 831.971 363.182 844 422 844C480.818 844 536.826 831.971 587.697 810.24Z"
            :fill="`url(#paint4_linear_${key})`"
        />
        <path
            :key="`path5-${key}`"
            d="M843.995 413.56H0.00476074C0.90267 367.797 9.0866 323.82 23.4446 282.74H820.555C834.914 323.82 843.097 367.797 843.995 413.56Z"
            :fill="`url(#paint5_linear_${key})`"
        />
        <path
            :key="`path6-${key}`"
            d="M814.245 265.86C752.16 110.089 599.939 0 422 0C244.061 0 91.8397 110.089 29.7551 265.86H814.245Z"
            :fill="`url(#paint6_linear_${key})`"
        />
        <defs>
            <linearGradient
                :key="`linearGradient0-${key}`"
                :id="`paint0_linear_${key}`"
                x1="422"
                y1="0"
                x2="422"
                y2="844"
                gradientUnits="userSpaceOnUse"
            >
                <stop stop-color="#C24CFC" />
                <stop
                    offset="1"
                    stop-color="#FFD500"
                />
            </linearGradient>
            <linearGradient
                :key="`linearGradient1-${key}`"
                :id="`paint1_linear_${key}`"
                x1="422"
                y1="0"
                x2="422"
                y2="844"
                gradientUnits="userSpaceOnUse"
            >
                <stop stop-color="#C24CFC" />
                <stop
                    offset="1"
                    stop-color="#FFD500"
                />
            </linearGradient>
            <linearGradient
                :key="`linearGradient2-${key}`"
                :id="`paint2_linear_${key}`"
                x1="422"
                y1="0"
                x2="422"
                y2="844"
                gradientUnits="userSpaceOnUse"
            >
                <stop stop-color="#C24CFC" />
                <stop
                    offset="1"
                    stop-color="#FFD500"
                />
            </linearGradient>
            <linearGradient
                :key="`linearGradient3-${key}`"
                :id="`paint3_linear_${key}`"
                x1="422"
                y1="0"
                x2="422"
                y2="844"
                gradientUnits="userSpaceOnUse"
            >
                <stop stop-color="#C24CFC" />
                <stop
                    offset="1"
                    stop-color="#FFD500"
                />
            </linearGradient>
            <linearGradient
                :key="`linearGradient4-${key}`"
                :id="`paint4_linear_${key}`"
                x1="422"
                y1="0"
                x2="422"
                y2="844"
                gradientUnits="userSpaceOnUse"
            >
                <stop stop-color="#C24CFC" />
                <stop
                    offset="1"
                    stop-color="#FFD500"
                />
            </linearGradient>
            <linearGradient
                :key="`linearGradient5-${key}`"
                :id="`paint5_linear_${key}`"
                x1="422"
                y1="0"
                x2="422"
                y2="844"
                gradientUnits="userSpaceOnUse"
            >
                <stop stop-color="#C24CFC" />
                <stop
                    offset="1"
                    stop-color="#FFD500"
                />
            </linearGradient>
            <linearGradient
                :key="`linearGradient6-${key}`"
                :id="`paint6_linear_${key}`"
                x1="422"
                y1="0"
                x2="422"
                y2="844"
                gradientUnits="userSpaceOnUse"
            >
                <stop stop-color="#C24CFC" />
                <stop
                    offset="1"
                    stop-color="#FFD500"
                />
            </linearGradient>
        </defs>
    </svg>
</template>

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

function randomString() {
    return Math.random().toString(36).substring(2, 15);
}

const key = ref(randomString());
</script>

Rendered SVG that does not show the icon:

<svg data-v-1825e573="" width="844" height="844" viewBox="0 0 844 844" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-4 h-4"><path d="M843.995 430.44H0.00476076C0.690863 465.408 5.63102 499.333 14.3292 531.72H829.671C838.369 499.333 843.309 465.408 843.995 430.44Z" fill="url(#paint0_linear_29_3)"></path><path d="M824.755 548.6H19.2449C28.5687 578.28 41.0839 606.548 56.3886 633H787.612C802.916 606.548 815.431 578.28 824.755 548.6Z" fill="url(#paint1_linear_29_3)"></path><path d="M777.31 649.88H66.6904C82.3345 674.213 100.411 696.834 120.576 717.4H723.424C743.589 696.834 761.666 674.213 777.31 649.88Z" fill="url(#paint2_linear_29_3)"></path><path d="M705.897 734.28H138.103C163.265 757.16 191.203 777.042 221.353 793.36H622.647C652.797 777.042 680.735 757.16 705.897 734.28Z" fill="url(#paint3_linear_29_3)"></path><path d="M587.697 810.24H256.303C307.175 831.971 363.182 844 422 844C480.818 844 536.826 831.971 587.697 810.24Z" fill="url(#paint4_linear_29_3)"></path><path d="M843.995 413.56H0.00476074C0.90267 367.797 9.0866 323.82 23.4446 282.74H820.555C834.914 323.82 843.097 367.797 843.995 413.56Z" fill="url(#paint5_linear_29_3)"></path><path d="M814.245 265.86C752.16 110.089 599.939 0 422 0C244.061 0 91.8397 110.089 29.7551 265.86H814.245Z" fill="url(#paint6_linear_29_3)"></path><defs><linearGradient id="paint0_linear_29_3" x1="422" y1="0" x2="422" y2="844" gradientUnits="userSpaceOnUse"><stop stop-color="#C24CFC"></stop><stop offset="1" stop-color="#FFD500"></stop></linearGradient><linearGradient id="paint1_linear_29_3" x1="422" y1="0" x2="422" y2="844" gradientUnits="userSpaceOnUse"><stop stop-color="#C24CFC"></stop><stop offset="1" stop-color="#FFD500"></stop></linearGradient><linearGradient id="paint2_linear_29_3" x1="422" y1="0" x2="422" y2="844" gradientUnits="userSpaceOnUse"><stop stop-color="#C24CFC"></stop><stop offset="1" stop-color="#FFD500"></stop></linearGradient><linearGradient id="paint3_linear_29_3" x1="422" y1="0" x2="422" y2="844" gradientUnits="userSpaceOnUse"><stop stop-color="#C24CFC"></stop><stop offset="1" stop-color="#FFD500"></stop></linearGradient><linearGradient id="paint4_linear_29_3" x1="422" y1="0" x2="422" y2="844" gradientUnits="userSpaceOnUse"><stop stop-color="#C24CFC"></stop><stop offset="1" stop-color="#FFD500"></stop></linearGradient><linearGradient id="paint5_linear_29_3" x1="422" y1="0" x2="422" y2="844" gradientUnits="userSpaceOnUse"><stop stop-color="#C24CFC"></stop><stop offset="1" stop-color="#FFD500"></stop></linearGradient><linearGradient id="paint6_linear_29_3" x1="422" y1="0" x2="422" y2="844" gradientUnits="userSpaceOnUse"><stop stop-color="#C24CFC"></stop><stop offset="1" stop-color="#FFD500"></stop></linearGradient></defs></svg>

Rendered SVG that does show the icon:

<svg data-v-1825e573="" width="844" height="844" viewBox="0 0 844 844" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-4 h-4"><path d="M843.995 430.44H0.00476076C0.690863 465.408 5.63102 499.333 14.3292 531.72H829.671C838.369 499.333 843.309 465.408 843.995 430.44Z" fill="url(#paint0_linear_29_3)"></path><path d="M824.755 548.6H19.2449C28.5687 578.28 41.0839 606.548 56.3886 633H787.612C802.916 606.548 815.431 578.28 824.755 548.6Z" fill="url(#paint1_linear_29_3)"></path><path d="M777.31 649.88H66.6904C82.3345 674.213 100.411 696.834 120.576 717.4H723.424C743.589 696.834 761.666 674.213 777.31 649.88Z" fill="url(#paint2_linear_29_3)"></path><path d="M705.897 734.28H138.103C163.265 757.16 191.203 777.042 221.353 793.36H622.647C652.797 777.042 680.735 757.16 705.897 734.28Z" fill="url(#paint3_linear_29_3)"></path><path d="M587.697 810.24H256.303C307.175 831.971 363.182 844 422 844C480.818 844 536.826 831.971 587.697 810.24Z" fill="url(#paint4_linear_29_3)"></path><path d="M843.995 413.56H0.00476074C0.90267 367.797 9.0866 323.82 23.4446 282.74H820.555C834.914 323.82 843.097 367.797 843.995 413.56Z" fill="url(#paint5_linear_29_3)"></path><path d="M814.245 265.86C752.16 110.089 599.939 0 422 0C244.061 0 91.8397 110.089 29.7551 265.86H814.245Z" fill="url(#paint6_linear_29_3)"></path><defs><linearGradient id="paint0_linear_29_3" x1="422" y1="0" x2="422" y2="844" gradientUnits="userSpaceOnUse"><stop stop-color="#C24CFC"></stop><stop offset="1" stop-color="#FFD500"></stop></linearGradient><linearGradient id="paint1_linear_29_3" x1="422" y1="0" x2="422" y2="844" gradientUnits="userSpaceOnUse"><stop stop-color="#C24CFC"></stop><stop offset="1" stop-color="#FFD500"></stop></linearGradient><linearGradient id="paint2_linear_29_3" x1="422" y1="0" x2="422" y2="844" gradientUnits="userSpaceOnUse"><stop stop-color="#C24CFC"></stop><stop offset="1" stop-color="#FFD500"></stop></linearGradient><linearGradient id="paint3_linear_29_3" x1="422" y1="0" x2="422" y2="844" gradientUnits="userSpaceOnUse"><stop stop-color="#C24CFC"></stop><stop offset="1" stop-color="#FFD500"></stop></linearGradient><linearGradient id="paint4_linear_29_3" x1="422" y1="0" x2="422" y2="844" gradientUnits="userSpaceOnUse"><stop stop-color="#C24CFC"></stop><stop offset="1" stop-color="#FFD500"></stop></linearGradient><linearGradient id="paint5_linear_29_3" x1="422" y1="0" x2="422" y2="844" gradientUnits="userSpaceOnUse"><stop stop-color="#C24CFC"></stop><stop offset="1" stop-color="#FFD500"></stop></linearGradient><linearGradient id="paint6_linear_29_3" x1="422" y1="0" x2="422" y2="844" gradientUnits="userSpaceOnUse"><stop stop-color="#C24CFC"></stop><stop offset="1" stop-color="#FFD500"></stop></linearGradient></defs></svg>

Okay, now I am interested in why this fixed the problem and what the problem actually is. Could somebody help me explain it?


Solution

  • The 2 last snippets of code are exactly the same.

    This is probably related to the fact that you need to have unique ids on your page and maybe some hydration/lifecycle hooks messed up that one.

    The browser may still display it sometimes because it's clever enough. But as a whole, it doesn't sound like a Vue/Nuxt-specific issue.

    Maybe Ionic is the issue here too, not sure because I do not have any experience with that one specifically. Hence I could recommend trying those icons instead and see if those battle-tested ones also have a similar issue. Idea would be to narrow down the things that doesn't work as much as possible.