# Integration with Next.js

[Next.js](https://nextjs.org/) is a web framework that allows you to build websites very quickly and GraphQL Yoga can be integrated with Next.js easily as [a custom route handler](https://nextjs.org/docs/app/building-your-application/routing/router-handlers).

## Installation [Permalink for this section](/content/graphql/yoga-server/docs/integrations/integration-with-nextjs#installation/index.html)

```
npm i graphql-yoga graphql
```

```
pnpm add graphql-yoga graphql
```

```
yarn add graphql-yoga graphql
```

```
bun add graphql-yoga graphql
```

## Example [Permalink for this section](/content/graphql/yoga-server/docs/integrations/integration-with-nextjs#example/index.html)

app/api/graphql/route.ts

```
// Next.js Custom Route Handler: https://nextjs.org/docs/app/building-your-application/routing/router-handlers
import { createSchema, createYoga } from 'graphql-yoga'

interface NextContext {
  params: Promise<Record<string, string>>
}

const { handleRequest } = createYoga<NextContext>({
  schema: createSchema({
    typeDefs: /* GraphQL */ `
      type Query {
        greetings: String
      }
    `,
    resolvers: {
      Query: {
        greetings: () => 'This is the `greetings` field of the root `Query` type'
      }
    }
  }),

graphqlEndpoint: '/api/graphql',
  fetchAPI: { Response }
})

export { handleRequest as GET, handleRequest as POST, handleRequest as OPTIONS }
```

> You can also check a full example on our GitHub repository [here](https://github.com/graphql-hive/graphql-yoga/tree/main/examples/nextjs-app)

### Using legacy Pages Directory [Permalink for this section](/content/graphql/yoga-server/docs/integrations/integration-with-nextjs#using-legacy-pages-directory/index.html)

The App Router and custom Route Handlers only exist since NextJS 13. If you are using an older version of NextJS or still using Pages Directory layout, you can still use GraphQL Yoga as an [API Route](https://nextjs.org/docs/pages/building-your-application/routing/api-routes).

pages/api/graphql.ts

```
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from 'next'
import { createSchema, createYoga } from 'graphql-yoga'

export const config = {
  api: {
    // Disable body parsing (required for file uploads)
    bodyParser: false
  }
}

const schema = createSchema({
  typeDefs: /* GraphQL */ `
    type Query {
      greetings: String
    }
  `,
  resolvers: {
    Query: {
      greetings: () => 'This is the `greetings` field of the root `Query` type'
    }
  }
})

export default createYoga<{ req: NextApiRequest, res: NextApiResponse }>({
  schema,
  graphqlEndpoint: '/api/graphql'
})
```

> You can also check a full example on our GitHub repository [here](https://github.com/graphql-hive/graphql-yoga/tree/main/examples/nextjs-legacy-pages)

## WebSockets for subscriptions [Permalink for this section](/content/graphql/yoga-server/docs/integrations/integration-with-nextjs#websockets-for-subscriptions/index.html)

WebSockets cannot be used with [Next.js API Routes](https://nextjs.org/docs/api-routes/introduction), we therefore have to create a [custom Next.js server](https://nextjs.org/docs/advanced-features/custom-server) that will serve the GraphQL API, WebSockets and the rest of Next.js content.

### Installation [Permalink for this section](/content/graphql/yoga-server/docs/integrations/integration-with-nextjs#installation-1/index.html)

```
npm i graphql-yoga graphql ws graphql-ws
```

```
pnpm add graphql-yoga graphql ws graphql-ws
```

```
yarn add graphql-yoga graphql ws graphql-ws
```

```
bun add graphql-yoga graphql ws graphql-ws
```

### Example [Permalink for this section](/content/graphql/yoga-server/docs/integrations/integration-with-nextjs#example-1/index.html)

server.js

```
const { createServer } = require('http')
const { WebSocketServer } = require('ws')
const { createYoga, createSchema } = require('graphql-yoga')
const { useServer } = require('graphql-ws/use/ws')
const { parse } = require('url')
const next = require('next')
const { setTimeout: setTimeout$ } = require('timers/promises')

const dev = process.env.NODE_ENV !== 'production'
const hostname = 'localhost'
const port = 3000

const app = next({ dev, hostname, port })
const graphqlEndpoint = '/api/graphql'

const yoga = createYoga({
  graphqlEndpoint,
  graphiql: {
    subscriptionsProtocol: 'WS'
  },
  schema: createSchema({
    typeDefs: /* GraphQL */ `
      type Query {
        hello: String!
      }
      type Subscription {
        clock: String!
      }
    `,
    resolvers: {
      Query: {
        hello: () => 'world'
      },
      Subscription: {
        clock: {
          async *subscribe() {
            for (let i = 0; i < 5; i++) {
              yield { clock: new Date().toString() }
              await setTimeout$(1_000)
            }
          }
        }
      }
    }
  })
})

;(async () => {
  await app.prepare()
  const handle = app.getRequestHandler()

const server = createServer(async (req, res) => {
    try {
      const url = parse(req.url, true)

if (url.pathname.startsWith(graphqlEndpoint)) {
        await yoga(req, res)
      } else {
        await handle(req, res, url)
      }
    } catch (err) {
      console.error(`Error while handling ${req.url}`, err)
      res.writeHead(500).end()
    }
  })

const wsServer = new WebSocketServer({ server, path: graphqlEndpoint })

useServer(
    {
      execute: args => args.rootValue.execute(args),
      subscribe: args => args.rootValue.subscribe(args),
      onSubscribe: async (ctx, _id, params) => {
        const { schema, execute, subscribe, contextFactory, parse, validate } = yoga.getEnveloped({
          ...ctx,
          req: ctx.extra.request,
          socket: ctx.extra.socket,
          params
        })

const args = {
          schema,
          operationName: params.operationName,
          document: parse(params.query),
          variableValues: params.variables,
          contextValue: await contextFactory(),
          rootValue: {
            execute,
            subscribe
          }
        }

const errors = validate(args.schema, args.document)
        if (errors.length) return errors
        return args
      }
    },
    wsServer
  )

await new Promise((resolve, reject) =>
    server.listen(port, err => (err ? reject(err) : resolve()))
  )

console.log(`
> App started!
  HTTP server running on http://${hostname}:${port}
  GraphQL WebSocket server running on ws://${hostname}:${port}${graphqlEndpoint}
`)
})()
```

### Running Next.js [Permalink for this section](/content/graphql/yoga-server/docs/integrations/integration-with-nextjs#running-nextjs/index.html)

Now that we have the custom server implemented, you start it by running:

```
node server.js
```

> You can also check a full example on our GitHub repository [here](https://github.com/graphql-hive/graphql-yoga/tree/main/examples/nextjs-ws)
