Skip to content

slavanossar/nuxt-payload-template

Repository files navigation

nuxt-payload-template

⚠️ Work In Progress

This template is slightly opinionated based on my main use case for client work, but the core monorepo structure is still a good basis for any Nuxt/Payload project.

I update the repo and packages manually as I continue to refine things during the course of my projects.

If you have any questions/suggestions, feel free to open up an issue.

Old version that uses Payload CMS v2 available on v2 branch

A Nuxt 3 + TypeScript starter template, with Payload CMS 3.

Requirements

Usage

# Install packages
pnpm install

# Create .env interactively
pnpm run configure-env

# Update packages interactively (minor versions)
pnpm run update

# Update packages interactively (major versions)
pnpm run update-latest

# Start dev server
pnpm run dev

# Generate gql exports, possibleTypes, and Payload types (run while dev server is active)
pnpm run generate

# Build for production
pnpm run build

# Start server
pnpm run start

Setup

Environment Variables

Environment variables are defined in .env and shared between apps with dotenv-cli. Variables prefixed with PAYLOAD_PUBLIC_ are exposed to Payload's client-side app.

Running pnpm configure-env will guide you through creating a .env file.

Variable Default Description
NITRO_HOST 0.0.0.0 Host for Nuxt's Nitro server
NITRO_PORT 3000 Port used by Nitro's server
SITE_NAME Nuxt x Payload The title of the site (used for page title templates, etc.)
NEXT_PUBLIC_SITE_URL - URL of the site, including protocol
PORT 3001 Port used by Payload's Next.js server
NEXT_PUBLIC_PAYLOAD_API_ROUTE /payload-api Route used for Payload's API
DATABASE_NAME nuxt-payload The name of the MongoDB database
PAYLOAD_SECRET - A secret key used for encrypting Payload data/sessions
S3_REGION - AWS S3 region
S3_BUCKET - AWS S3 bucket name
S3_ACCESS_KEY_ID - AWS S3 access key ID
S3_SECRET_ACCESS_KEY - AWS S3 secret access key
CLOUDFRONT_DOMAIN - CloudFront domain for serving assets

Custom Local Hostname

You will need to set up a custom local hostname for local development, using NGINX and the provided nginx-conf-examples/local.conf config. If you use mkcert for local SSL certificates, you can use the provided nginx-conf-examples/local-mkcert.conf.

Make sure the update the server_name directive, any changes to the default ports, and the ssl_certificate and ssl_certificate_key paths if required.

You will also need our hosts file so the custom hostname resolves to 127.0.0.1:

# /etc/hosts

127.0.0.1       example.test

💡 hostctl is a nice CLI tool for managing your hosts file

DX

Payload Types

Payload types can be generated by running the generate command

pnpm run generate --filter payloadcms

You can easily access Payload's generated types within the Nuxt workspace using the #payload-types alias

import type { Image } from "#payload-types";

💡 Type imports must be explicit since Nuxt 3.8, so make sure to use import type ...

Type-safe Relationship Fields

Payload Relationship fields for GraphQL queries are typed as string | MyCollectionType (or string[] | MyCollectionType[] when the field uses the hasMany option). This is because querying the field without any subfields will return the document ID:

# Will return an ID
query GetRelationship {
  doc {
    relationshipField
  }
}

# Will return an object
query GetRelationship {
  doc {
    relationshipField {
      subField
    }
  }
}

This can cause type issues when using these fields within Nuxt, so there are two composables that can be used to check the type of relationship fields.

<script lang="ts" setup>
const doc = useRelationshipField(data.doc.relationshipField); // RelationshipType | null
const docs = useRelationshipArrayField(data.doc.relationshipHasManyField); // RelationshipType[]
</script>

GraphQL Exports

GraphQL documents are generated from the .gql files in apps/nuxt/graphql, and output to apps/nuxt/graphql/index.js. You can regenerate the exports using the generate script

pnpm run generate --filter nuxt

💡 Nuxt's generate script will also query the Payload schema, so make sure the Payload app is running (via dev server or otherwise)

usePayloadPage composable

The Pages collection is set up for building predefined page templates, and the usePayloadPage composable makes it easy to retrieve page data using Apollo, while also automatically set any SEO/Meta values provided by @payloadcms/plugin-seo.

<script lang="ts" setup>
const doc = await usePayloadPage("Home");
const fields = doc.value?.homeFields;
</script>

Globals

Globals data is located in the @/stores/globals store, and is preloaded during SSR (see apps/nuxt/app.vue).

About

nuxt3 + payload + typescript + pinia + tailwind

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published