Next.js (Pages Router)

How to use PMKIN with Next.js (Pages Router)

This guide walks you through integrating PMKIN with your Next.js application using the Pages Router approach.

Installation and Setup

Start by adding the necessary packages to your Next.js project:

npm install @apollo/client graphql react-markdown

Set up your PMKIN API key as an environment variable. Create a .env.local file in your project root:

PMKIN_API_KEY=your_api_key_here

Creating the Apollo Client

Create a new file lib/apollo-client.ts:

import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client'
import { setContext } from '@apollo/client/link/context'

const httpLink = createHttpLink({
  uri: 'https://pmkin.io/graphql'
})

const authLink = setContext((_, { headers }) => {
  const pmkinApiKey = process.env.PMKIN_API_KEY

  if (!pmkinApiKey) {
    throw new Error('PMKIN_API_KEY is not set.')
  }

  return {
    headers: {
      ...headers,
      authorization: `Bearer ${pmkinApiKey}`
    }
  }
})

export const client = new ApolloClient({
  cache: new InMemoryCache(),
  link: authLink.concat(httpLink)
})

Listing Documents

Create a new file pages/blog/index.tsx:

import { gql } from "@apollo/client"
import Link from "next/link"

import { client } from "../../lib/apollo-client"

const GET_DOCUMENTS = gql`
  query GetDocuments {
    documents(includeDrafts: false) {
      id
      title
      slug
      metaDescription
    }
  }
`

interface Document {
  id: string
  title: string
  slug: string
  metaDescription: string
}

interface BlogListProps {
  documents: Document[]
}

export async function getStaticProps() {
  const { data } = await client.query({ query: GET_DOCUMENTS })

  return {
    props: {
      documents: data.documents
    },
    revalidate: 60 // Revalidate every 60 seconds
  }
}

export default function BlogList({ documents }: BlogListProps) {
  return (
    <div>
      <h1>Blog Posts</h1>
      {documents.map((doc) => (
        <article key={doc.id}>
          <h2><Link href={`/blog/${doc.slug}`}>{doc.title}</Link></h2>
          <p>{doc.metaDescription}</p>
        </article>
      ))}
    </div>
  )
}

Rendering Document Content

Create a new file pages/blog/[slug].tsx:

import { gql } from "@apollo/client"
import Head from "next/head"
import ReactMarkdown from "react-markdown"

import { client } from "../../lib/apollo-client"

const GET_DOCUMENT = gql`
  query GetDocument($slug: String!) {
    documentBySlug(slug: $slug) {
      id
      title
      markdown
      metaTitle
      metaDescription
    }
  }
`

interface Document {
  id: string
  title: string
  markdown: string
  metaTitle: string
  metaDescription: string
}

interface BlogPostProps {
  document: Document
}

export async function getStaticPaths() {
  // Implement this function to return a list of all possible slug values
  // You might need to fetch all documents and extract their slugs
  return {
    paths: [],
    fallback: "blocking"
  }
}

export async function getStaticProps({ params }: { params: { slug: string } }) {
  const { data } = await client.query({
    query: GET_DOCUMENT,
    variables: { slug: params.slug }
  })

  return {
    props: {
      document: data.documentBySlug
    },
    revalidate: 60 // Revalidate every 60 seconds
  }
}

export default function BlogPost({ document }: BlogPostProps) {
  return (
    <>
      <Head>
        <title>{document.metaTitle}</title>
        <meta name="description" content={document.metaDescription} />
      </Head>
      <article>
        <h1>{document.title}</h1>
        <ReactMarkdown>{document.markdown}</ReactMarkdown>
      </article>
    </>
  )
}

This setup provides a solid foundation for integrating PMKIN with your Next.js application using the Pages Router. Using PMKIN's API, you can expand on this by adding pagination, categories, or search functionality.