skip to Main Content

I have a project which is build in Nuxt 3 with a homepage which shows products. On that homepage, you can click on the title of the product and the product details page opens up. I archive this by using <NuxtLink>

<NuxtLink :to="{ name: 'slug', params: { slug: product.slug }}">
    <p>{{ product.title }}</p>
</NuxtLink>

When the user click on that link, the [slug].vue component will show the product details page. So far, so good. However, this leads to the [slug].vue component fetching the product data from the API again using its slug like this:

const { data } = await useFetch(runtimeConfig.public.api.product.view + `/${slug}`);

This behavior is also needed when the user visits the product details page directly from a link he saw on e.g. Facebook etc. But when the user clicks on the <NuxtLink> from the homepage, I would like to pass my product object to the [slug].vue component, as the homepage already has all needed information about the product the [slug].vue component needs to render.

If I will be able to pass my product object to the [slug].vue component, I could skip the extra API fetch and present the data right away to the user, increasing page speed and user experience.

I have already written the necessary code I need within my [slug].vue component to determine whether the props are empty and the component needs to fetch them from the API or the component can just use the props being passed and skip the fetch:

<script setup lang="ts">
  const { slug } = useRoute().params;
  const runtimeConfig = useRuntimeConfig()
  const route = useRoute()

  // Define component props
  const props = defineProps({
    product: null
  });

  // Computed property to determine whether data needs to be fetched
  const fetchData = computed(() => {
    return !props.product; // If props.data is not provided, fetch data
  });

  // Data ref to store fetched data
  const product = ref(null);

  // Fetch data from the API if fetchData is true
  if (fetchData.value) {
    const { data } = await useFetch(runtimeConfig.public.api.product.view + `/${slug}`);
    product.value = data.value;
  }
</script>

However, I am failing at passing my product object from my <NuxtLink> to the props of my [slug].vue component. How can I archive that?

I do not want to pass my product object from my homepage to my [slug].vue component using params. This will not work as the product object is quite long. I could stringify it with JSON.stringify() but I also don’t want to pass data via my URL except the slug. Furthermore, the URL would also look very ugly, passing a very long JSON string to it.

I also do not want to use a storage like Pinia. I want to make use of the available props functionality, which was build to pass data between components.

If you have any other idea, how I can pass the data to my [slug].vue component from the homepage, let me know.

Kind regards

2

Answers


  1. <NuxtLink> is just a router link. You will not be able to pass data through it for the next page.
    But you can save, for example, in some store or localStorage this data after @click on <NuxtLink>, and process it on the next view.

    Login or Signup to reply.
  2. You should use a store in your project. create a store.js file in store folder in your root directory.

    export const store = reactive({
       products: [],
    })
    

    then when you fetch your products from the top index page you store them in the store

    import { store } from "@/store/store.js";
    
    const { result } =  await $fetch('endpoint')
    store.jobs = result
    

    then in your individual product page you first check if your store has your products

    let product
    if(store.products.length){
       product = store.products.find(//find your product in the array//)
    }else{
       const { data } = await useFetch(runtimeConfig.public.api.product.view + `/${slug}`);
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search