# Fetching Data

# Static Nuxt

Since version 2.14.0 (opens new window), Nuxt is capable of caching data fetched during the static generation process. This data is saved as JSON, and is retrieved as needed during client-side navigation. This means that the data fetched at build time persists after the build process is complete. Let's examine why that's important.

We'll consider what Nuxt does with a ~/pages/products/brand-new-product Vue template:

<template>
  <div>
    <h1>{{ product.title }}</h1>
    <div>{{ product.price }}</div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      product: null,
    }
  },
  async fetch() {
    this.product = await this.$nacelle.data.product({
      handle: 'brand-new-product',
    })
  },
}
</script>

At build time, Nuxt will create a HTML document that looks something like this:

<!DOCTYPE html>
<html data-n-head-ssr lang="en">
  <head>
    <title>My Digital Storefront</title>
    <meta data-n-head="ssr" charset="utf-8" />
  </head>
  <body>
    <div data-server-rendered="true" id="__nuxt">
      <div>
        <h1>Brand New Product</h1>
        <div>$50</div>
      </div>
    </div>
    <script
      defer
      src="/_nuxt/static/some-webpack-chunk-id/products/brand-new-product/state.js"
    ></script>
  </body>
</html>

If we were to navigate directly to this page in a browser, we would receive the HTML containing the product's title and price. But if we were to first navigate to the site's homepage, and then click on a <nuxt-link> (opens new window) that brought us to /products/brand-new-product, instead of a full reload, Vue hydration (opens new window) would dynamically assemble the page's resources for a quick and seamless client-side navigation experience.

When the page component hydrates, it will fetch the product data from /_nuxt/static/some-webpack-chunk-id/products/brand-new-product/state.js and use that data to populate the Title and Price values in the DOM (opens new window).

This is why JAMstack static sites can be very fast and durable compared to traditional Single Page Applications (SPAs) or full-stack server-based apps. The data that the page needs for hydration lives with the rest of the site's files. The page can get what it needs quickly, without depending on an external data source that's susceptible to service outages.

# Fetching data with the Nacelle Cient JS SDK

The Nacelle Client JS SDK's data module provides a quick and easy way to fetch product, collection, content, and Nacelle space data from Nacelle's APIs. Please check out the data module docs for a complete list of available methods, with code examples.

# $nacelle

The Nacelle Nuxt Starter injects an instance of the Nacelle Client JS SDK as globally-available $nacelle plugin (opens new window) that can be used throughout your project's Vue templates.

# The fetch hook

Since Nuxt version 2.12, Nuxt has included a fetch (opens new window) hook which sits alongside a component's data, computed, and component lifecycle hooks (opens new window). As its name implies, the fetch hook is the preferred hook for fetching data.

WARNING

If your Nacelle Nuxt Starter's package.json version is less than 2.0.0, then you will need to add fetchOnServer: false (opens new window) in order to fetch data with this.$nacelle in the fetch hook:

<script>
export default {
  data() {
    return {
      product: null,
    }
  },
  async fetch() {
    this.product = await this.$nacelle.data.product({ handle: 'example' })
  },
  fetchOnServer: false,
}
</script>

# Examples

Let's use $nacelle in the fetch hook to fetch some data for our digital storefront.

# Fetching a Product

<template>
  <pre>{{ formattedProduct }}</pre>
</template>

<script>
export default {
  data() {
    return {
      product: null,
    }
  },
  async fetch() {
    this.product = await this.$nacelle.data.product({
      handle: 'my-great-product',
    })
  },
  computed: {
    formattedProduct() {
      return JSON.stringify(this.product, null, 2)
    },
  },
}
</script>

# Fetching a Page

<template>
  <pre>{{ formattedPage }}</pre>
</template>

<script>
export default {
  data() {
    return {
      page: null,
    }
  },
  async fetch() {
    this.page = await this.$nacelle.data.page({
      handle: 'terms-and-conditions',
    })
  },
  computed: {
    formattedPage() {
      return JSON.stringify(this.page, null, 2)
    },
  },
}
</script>

# Fetching an arbitrary piece of content

<template>
  <pre>{{ formattedFooter }}</pre>
</template>

<script>
export default {
  data() {
    return {
      footer: null,
    }
  },
  async fetch() {
    this.footer = await this.$nacelle.data.content({
      handle: 'global-footer',
      type: 'footer',
    })
  },
  computed: {
    formattedFooter() {
      return JSON.stringify(this.footer, null, 2)
    },
  },
}
</script>