Nuxt3 ️ GraphQL
Tags: nuxt3, graphql, fullstack
Published: 2022-02-23 13:21:35

_The repository containing the example code for this series is [available here](https://github.com/lewebsimple/nuxt3-fullstack)._

For some time I've been trying to assemble a full stack solution based on Nuxt and GraphQL. Now that Nuxt3 RC ~~is just around the corner~~ has landed, I figured it would be interesting to explore its full stack capabilities with the following goals in mind:

* Declarative database modelling
* Code-first schema definition
* End to end type safety
* SSR friendly GraphQL client
* Isomorphic authentication / authorization
* Form generation and validation

Conveniently, these features correspond to the following projects:

- [Prisma ORM](https://www.prisma.io/)
- ~~[GraphQL Nexus](https://nexusjs.org/)~~ [Pothos GraphQL](https://pothos-graphql.dev/)
- [GraphQL Code Generator](https://www.graphql-code-generator.com/)
- [@urql/vue](https://formidable.com/open-source/urql/docs/basics/vue/)
- ~~[Nexus Shield](https://github.com/Sytten/nexus-shield)~~ [GraphQL AuthZ](https://github.com/AstrumU/graphql-authz)
- [FormKit](https://formkit.com/)

This series aims to document my progress towards integrating these in a full stack application boilerplate.

## Initializing the Nuxt3 project

First things first, let's create a Nuxt3 project:
```shell
npx nuxi init nuxt3-fullstack
cd nuxt3-fullstack && yarn install
```

Starting the development server will generate the `.nuxt/tsconfig.json` TypeScript configuration extended by `tsconfig.json`:
```shell
yarn dev
```

### Automatic code formatting

It's also a good idea to add ESLint for automatic code formatting with the preset of your choice:
```shell
yarn add -D eslint @lewebsimple/eslint-config-vue
```

The ESLint configuration can be defined with the following section inside `package.json` :
```json
"eslintConfig": {
  "extends": "@lewebsimple/eslint-config-vue"
}
```

If your IDE is configured properly, saving a source file should now reformat it automatically (this might require restarting the TypeScript language service). Otherwise, we can manually lint the project with the following script (which should be added to the corresponding section in `package.json`):
```json
"lint": "eslint --fix --ignore-path .gitignore ."
```

### Bonus: Adding Tailwind CSS

Let's add [Tailwind CSS](https://tailwindcss.com/) because we're really cool:
```shell
yarn add -D @nuxtjs/tailwindcss @tailwindcss/forms @tailwindcss/line-clamp @tailwindcss/typography
```

We need to add `@nuxtjs/tailwindcss` to `modules` in `nuxt.config.ts`:
```typescript
import { defineNuxtConfig } from "nuxt3";

// https://v3.nuxtjs.org/docs/directory-structure/nuxt.config
export default defineNuxtConfig({
  modules: ["@nuxtjs/tailwindcss"],
  tailwindcss: {
    viewer: false,
  },
});
```

Then generate and adjust `tailwind.config.js`:
```shell
npx tailwindcss init
```

```javascript
/* eslint-disable @typescript-eslint/no-var-requires */

module.exports = {
  theme: {
    extend: {
      container: {
        center: true,
        padding: "1.5rem",
      },
      typography: {
        DEFAULT: {
          css: {
            maxWidth: "none",
          },
        },
      },
    },
  },
  plugins: [
    require("@tailwindcss/forms"),
    require("@tailwindcss/line-clamp"),
    require("@tailwindcss/typography"),
  ],
};
```

To display a basic frontend design, we'll delete `app.vue`, create a default layout in `layouts/default.vue`:
```vue
<template>
  <div class="container py-6">
    <NuxtPage />
  </div>
</template>
```

... and a default front page in `pages/index.vue`:
```vuejs
<template>
  <div id="front-page" class="prose">
    <h1>Nuxt3 ❤️ GraphQL</h1>
  </div>
</template>
```

Wow, such a nice design!

### Finishing touches

Now is also a good time to set the project name, description, version and license in `package.json` and to commit our changes to Git.

We can also setup `release-it` to manage our release process:
```shell
yarn add -D release-it
```

We can create new releases with the following script in `package.json`:
```json
"release": "release-it"
```

With our Nuxt3 project properly initialized, we’re ready to start adding some features!