#Dealing with SSR and Math.random

1 messages · Page 1 of 1 (latest)

vale silo
#

Hey everyone,

I'm new to Nuxt coming from SvelteKit, I love the idea of auto-imports and love the work you are doing on Nuxt. One thing I'm struggling with here is how to make this code SSR friendly.

<script setup lang="ts">
interface Props {
    text: string;
}

const props = defineProps<Props>();

const text = computed(() => {
    const splitWord = props.text.split(' ').filter(Boolean);
    const splitLetter = splitWord.map((word) => word.split('').map((letter) => ({ letter, shift: false })));

    splitLetter.map((word) => {
        const randomLetter = Math.round(Math.random() * (word.length - 1));
        word[randomLetter].shift = true;
    });

    return splitLetter;
});
</script>

<template>
    <template v-for="(word, index) in text">
        <span>
            <span v-for="letter in word" :class="{ 'font-heading': letter.shift }">
                {{ letter.letter }}
            </span>
        </span>
        <span v-if="index !== word.length - 1"> </span>
    </template>
</template>

In our design we have one letter that has a different font, which letter in the world should be random each time. I've tried useState(() => Math.round(...)) but it will only key per file so it being in a each isn't right. Is the solution to break this down into smaller components? I'd prefer to not have the overhead.

abstract finch
#

make this code client only if you don't want to use useState and any overhead

vale silo
#

I wrapped it in <ClientOnly /> as a solution with the fallback value of text however, it seems to create layout shift on load which is very jarring.

#

What would be ideal would be to run this on the server and send the HTML, I know you can do that with islands but it isn't stable yet.

abstract finch
#

Such things better to process on client. To prevent layout shift, just reserve space. Or use useState 😁

vale silo
#

Thanks @abstract finch, wrapping it in useState rather than computed caused the text for every use of that component to be the same. I'm just going to stick with it changing on hydration 🙂

#

Though for future reference it would be good to know how to do this with useState, I don't assign a key but useState without a key is per file not per component usage.

abstract finch
#

try to use ref for math.random value in setup. Then use computed to calculate letters