Build Responsive Cross-Platform Vue Apps with Quasar Framework and GraphQL
Tags: vue, graphql, javascript
Published: 2022-09-16 09:14:53

---
title: Build Responsive Cross-Platform Vue Apps with Quasar Framework and GraphQL
published: true
date: 2022-04-14 10:42:00 UTC
tags: vue,graphql,javascript
canonical_url: https://hasura.io/blog/build-responsive-cross-platform-vue-apps-with-quasar-framework-and-graphql/
---

![Build Responsive Cross-Platform Vue Apps with Quasar Framework and GraphQL](https://hasura.io/blog/content/images/2022/04/quasar-1.png)

**TL;DR** : Build responsive SPAs, SSR Apps, PWAs, Hybrid Mobile / Electron Apps using a single codebase with [Quasar Framework](https://quasar-framework.org) and the [Hasura GraphQL Engine](https://hasura.io/graphql/). Instant setup. Tutorial/boilerplate -> [quasar-framework-vue-graphql](https://github.com/hasura/graphql-engine/tree/master/community/sample-apps/quasar-framework-vue-graphql)

### Quasar Framework

Quasar Framework is a high-performance Vue.js framework that enables developers to build different types of applications with a single codebase.

With Quasar, you can have a single codebase for:

- Single Page Apps (SPA)
- Server-Side Rendered Apps (SSR)
- iOS/Android Mobile Apps
- Desktop Apps
- PWAs
- Hybrid Apps

In simple terms, Quasar allows you to build cross-platform applications.

Although it is powered by Vue.js, it comes with its own set of built-in web components that can be imported to construct user interfaces.

### Hasura with Quasar

[Hasura](https://hasura.io/) is an [open-source GraphQL engine](https://github.com/hasura/graphql-engine) that gives you real-time GraphQL APIs on new or existing Postgres databases. It comes with built-in support for stitching custom GraphQL APIs, and it allows you to trigger webhooks on database changes.

Hasura GraphQL fits in this workflow of building cross-platform apps neatly. All the clients (mobile app/electron app) use the same set of APIs controlled by the same set of permissions and auth. That means it can leverage the power of Postgres. Quasar gives endless possibilities with one codebase, and a standard GraphQL API from Hasura adds to the easier development workflow.

[![Deploy to Hasura button](https://camo.githubusercontent.com/949a2db267b00f49757865d585f16687118d796d41064e21c3d933d21884d533/68747470733a2f2f6772617068716c2d656e67696e652d63646e2e6861737572612e696f2f696d672f6465706c6f795f746f5f6861737572612e706e67)](https://cloud.hasura.io/signup)

In the next step, you will learn how to configure the Apollo Client with Quasar and perform GraphQL Queries.

### Quasar App Extensions

Quasar enables developers to extend the application’s functionalities with extensions. An example of an extension would be `@quasar/apollo`, which allows you to use GraphQL and the Apollo Client in your Quasar app.

In Quasar, you can install extensions as follows:

```
quasar ext add @quasar/apollo@next

```

The above command installs the extension and creates two additional files:

- `src/apollo/index.js` - you need to add your Hasura app endpoint in this file
- `src/boot/apollo.js` - you can leave this untouched

The next step is to register the extension in the `quasar.config.js` file. Open the file and add "apollo.js" in the `boot` array. See the part of the config file where you need to make the changes:

```
module.exports = configure(function (ctx) {
  return {
    boot: ["apollo.js"],
   };
});

```

You are done with the extension installation & configuration. The next step involves using the Apollo Client to perform GraphQL Queries.

## Fetch Authors

The main page of the application will list all the authors. You can click on the name of the authors to see their articles.

![Build Responsive Cross-Platform Vue Apps with Quasar Framework and GraphQL](https://hasura.io/blog/content/images/2022/04/Screenshot-2022-04-13-at-14.04.03.png)

Quasar comes with all sorts of UI components that you can use to create an application with a native feeling.

In the code snippet below, you make use of those UI components to build the user interface. Add this code in the `layouts/MainLayout.vue` file:

```
<template>
  <q-layout view="lHh Lpr lFf">
    <q-header elevated>
      <q-toolbar>
        <q-btn
          flat
          dense
          round
          icon="menu"
          aria-label="Menu"
          @click="toggleLeftDrawer"
        />

        <q-toolbar-title
          class="my-box cursor-pointer q-hoverable"
          @click="this.$router.push(`/`)"
        >
          Quasar App with Hasura GraphQL Engine
        </q-toolbar-title>

        <div>Running on Quasar v{{ $q.version }}</div>
      </q-toolbar>
    </q-header>

    <q-drawer v-model="leftDrawerOpen" show-if-above bordered>
      <q-list>
        <q-item-label header> Author List </q-item-label>

        <q-item v-for="author in authors" :key="author.id">
          <q-item-section class="my-box cursor-pointer q-hoverable">
            <q-item-label @click="fetchArticle(author)">
              {{ author.name }}
            </q-item-label>
            <q-item-label caption>ID: {{ author.id }}</q-item-label>
          </q-item-section>
        </q-item>
      </q-list>
    </q-drawer>

    <q-page-container>
      <router-view />
    </q-page-container>
  </q-layout>
</template>

```

The above code loops over an array of authors, and it also uses a method named `fetchArticles`. That means you need to retrieve the authors from the database and define the method for fetching articles.

Write the following code in the same file:

```
<script>
import { defineComponent, ref } from "vue";
import { useRouter } from "vue-router";
import { useQuery, useResult } from "@vue/apollo-composable";
import gql from "graphql-tag";

export default defineComponent({
  name: "MainLayout",

  setup() {
    const leftDrawerOpen = ref(false);
    const router = useRouter();

    const { result, loading, error } = useQuery(gql`
      query {
        author {
          id
          name
        }
      }
    `);

    const authors = useResult(result, null, (data) => data.author);

    const fetchArticle = (author) => {
      return router.push(`/author/${author.id}`);
    };

    return {
      authors,
      leftDrawerOpen,
      fetchArticle,
      toggleLeftDrawer() {
        leftDrawerOpen.value = !leftDrawerOpen.value;
      },
    };
  },
});
</script>

```

You use the Apollo Client to query the database and retrieve the authors. You also define the `fetchArticle` method, which routes users to the right page when clicking on the author’s name.

The code is still the same kind of code you would have written in a Vue.js app to make a GraphQL query with **vue-apollo**. The difference is the `<template>` part where Quasar uses native-like components to build hybrid apps.

## Fetch Articles

Each author can have one or more articles, so you need to build the "Articles" page to list those articles. You can use the Quasar CLI to create a new page:

```
quasar new page Articles

```

The command creates a `.vue` file in the `src/pages` folder. Now you need to reference it in the `routes` file so that the users can access it.

Open the `src/router/routes.js` and add the route:

```
{
    path: "/",
    component: () => import("layouts/MainLayout.vue"),
    children: [
      {
        path: "/author/:authorId",
        component: () => import("pages/Articles.vue"),
      },
      { path: "", component: () => import("pages/IndexPage.vue") },
    ],
  },

```

Observe the `/author/:authorId` path. You can see an example of such a URL in the image below.

![Build Responsive Cross-Platform Vue Apps with Quasar Framework and GraphQL](https://hasura.io/blog/content/images/2022/04/Screenshot-2022-04-13-at-14.58.12.png)

When you visit an author, you can see all the articles written by that author.

Go to the `src/pages/Articles.vue` file and replace the content with this template:

```
<template>
  <q-page padding>
    <q-item v-for="article in articles" :key="article.id">
      <q-item-section class="my-box cursor-pointer q-hoverable">
        <q-item-label>
          {{ article.title }}
        </q-item-label>
        <q-item-label caption>ID: {{ article.id }}</q-item-label>
        <q-item-label>
          {{ article.content }}
        </q-item-label>
      </q-item-section>
    </q-item>
  </q-page>
</template>

```

You are using the Quasar UI components to display the article:

- title
- id
- content

Now it's time to fetch the articles from the Hasura backend. Add the following code after the `template` section:

```
<script>
import { watch } from "vue";
import { useQuery, useResult } from "@vue/apollo-composable";
import { useRoute } from "vue-router";
import gql from "graphql-tag";

export default {
  name: "PageName",

  setup() {
    const route = useRoute();

    const { result, loading, error, refetch } = useQuery(
      gql`
        query articleQuery($authorId: Int!) {
          article(where: { author_id: { _eq: $authorId } }) {
            id
            title
            content
          }
        }
      `,
      {
        authorId: route.params.authorId,
      }
    );

    const articles = useResult(result, null, (data) => data.article);

    watch(
      () => route.params.authorId,
      async (newId) => {
        refetch({ authorId: newId });
      }
    );

    return {
      articles,
    };
  },
};
</script>

```

In the above code, you:

- use the Apollo Client to retrieve the articles from the database
- pass the `authorId` parameter, so it fetches the articles for that specific author
- re-fetch the articles when the author id (from the URL) changes

Thus, when you visit a URL like `https://your-app.com/author/1`, the page displays the articles of the author whose ID is "1".

## Build Targets

Quasar requires you to specify the mode of the app `spa|ssr|pwa|cordova|electron` and the target `cordova|electron` - in case it's a hybrid app. You can also specify themes like `material` and `ios`, which will appropriately apply each component’s styles.

You can read more about build targets [here](https://quasar.dev/quasar-cli-webpack/commands-list#build).

> There is a boilerplate and a short tutorial to help you get started quickly! Check it out on [Github](https://github.com/hasura/graphql-engine/tree/master/community/sample-apps/quasar-framework-vue-graphql).

Take it for a spin and let us know what you think. If you have any questions or run into any trouble, feel free to reach out to us on [Twitter](https://twitter.com/hasurahq), [Github](https://github.com/hasura/graphql-engine), or our [Discord server](https://discord.gg/vBPpJkS).