# Data Fetching

Data fetching is a crucial part of any frontend application. In the blökkli starterkit we made the data fetching
from Drupal as easy as possible while still providing the flexibility to fetch data from any source.

## Initial Page vs per Route Data fetching

To make the frontend as fast as possible, we split the data fetching into two parts: `initData` and `routeQuery`.

### InitData

The `initData` is usually fetched during the server-side rendering (SSR) of the initial page load and the payload is
then handed over to the client.
![page.png](/content/images/page.png){width=200px}
**Data fetched:**

* Navigation / Header / Footer
* Global configuration

The data is shared across all subsequent client request. To simplify the process, there is a `initData()`
[composable](/frontend/composables#useinitdata) that
can be used in any component.

### Route Query

The `routeQuery` is called for each route and fetches the data for a specific page. The data is then passed to the
components as props.

![content.png](/content/images/content.png){width=200px}

* Page content / paragraphs
* Translations per page
* Alias / redirects per page

You can find more information about the [routing](/frontend/routing) in the dedicated section.

## GraphQL fragments

To make the queries more readable and maintainable, we use fragments.
Each fragment is a small part of the query that can be reused in multiple queries.

Fragments for each component are stored in its own folder. All fragments are automatically imported and registered with
the
help of the Nuxt GraphQL Middleware module.

## Nuxt GraphQL Middleware

This module exposes GraphQL queries and mutations as fully typed API endpoints. It hides your GraphQL server from
public access and prevents bundling large queries.

To make development easier, the module detects changes in GraphQL files and automatically reloads the schema.

![middleware.png](/content/images/middleware.png){width=400px}
Learn more about the [Nuxt GraphQL Middleware](https://nuxt.com/modules/nuxt-graphql-middleware){target=_blank}.

## Data fetching for a specific page

To fetch data for a specific page, use the `useDrupalRouteQuery()` composable described in the [Routing]
(/frontend/routing)
section.

The `useDrupalRouteQuery()` composable returns all the data for a given path in a single GraphQL query. The data is then
passed to the components as props. The route query is, in fact, a large graph / tree of fragments.

### Node Page Component

```graphql [components/Node/Page/fragment.graphql]
fragment nodePage on NodePage {
  uuid
  title
  lead: fieldLead
  hero: fieldHeroImage {
    ...mediaImage
  }
  canEdit: accessCheck(operation: "update")
  paragraphs: fieldParagraphs {
    ...paragraphsFieldItem
    props {
      ...paragraph
    }
  }
}
```

### TextImage Paragraph Component

```graphql [components/paragraphs/TextImage/fragment.graphql
fragment paragraphTextImage on ParagraphTextImage {
  title: fieldTitle
  text: fieldText
  image: fieldImage {
    ...mediaImage
  }
}
```

## Component Props

The component only needs the `paragraphTextImage` fragment to fetch the data. The other fragments are shared across
all paragraphs components and not duplicated in each component. The data fetched by the route query is passed to the
component as props. The components only need to define the props using typed fragment.

```vue [components/paragraphs/TextImage/index.vue]

<template>
  <div>
    ...
  </div>
</template>

<script lang="ts" setup>
  import type { ParagraphTextImageFragment } from '#graphql-operations'

  defineProps<{
    title?: string
    text?: string
    image: ParagraphTextImageFragment['image']
  }>()

</script>
```

