Skip to Content

WunderGraph with NextJS

Published: 2022-05-23

WunderGraph loves NextJS. WunderGraph uses NextJS as a frontend framework. We offer first class support for NextJS.

Our goal is to become the #1 data fetching framework for NextJS.

Architecture#

Let's have a look at the architecture of a NextJS application using WunderGraph.

Instead of manually integrating multiple APIs into the frontend code, we move this logic into the WunderNode.

Code Generation#

WunderGraph comes with code generation templates dedicated for NextJS. Our templates are all written in Typescript, Javascript is also possible. The generated client supports both client- and server side rendering. It's also possible to use the client for static sites.

Here's an example of a NextJS page to illustrate how you'd use the generated client. It contains a lot of comments for you to fully understand every aspect.

import {GetServerSideProps, NextPage} from 'next'
import {useLiveQuery, useMutation, useQuery, useSubscription, useWunderGraph} from "../generated/hooks";
import {FakeProductsResponse} from "../generated/models";
import {Client} from "../generated/client";
interface Props {
// use the generated types for typesafe props when using SSR
products?: FakeProductsResponse;
}
const IndexPage: NextPage<Props> = ({products}) => {
// get the WunderGraph client from the context to be able to login & logout users
// the user object contains information like email and name, if the user is logged in
const {client: {login, logout}, user} = useWunderGraph();
// call the FakeProducts Operation with a parameter (first 5) and the initial state from SSR
// passing data as initial state allows you to immediately render the component
// this is possible in case the data was fetched on the server side
const fakeProducts = useQuery.FakeProducts({input: {first: 5}, initialState: products});
// call the SetPrise mutation with inputs
// the inputs can be manipulated using the mutate (setPrice) function
const {mutate: setPrice, response: price} = useMutation.SetPrice({input: {price: 0, upc: "1"}});
// call the PriceUpdates Subscription
// once new data is available, the UI will update automatically
const priceUpdate = useSubscription.PriceUpdates();
// call the OasUsers Operation
// if the window blurs (user leaves tab or clicks away) and re-enters (clicking into the tab/window again)
// the Query will re-fire and trigger a re-render if the response changed
const oasUsers = useQuery.OasUsers({refetchOnWindowFocus: true});
// calls the Countries Operation
const countries = useQuery.Countries();
// calls the TopProducts liveQuery
// originally, the upstream only supports regular GraphQL Queries
// LiveQueries allow you to turn any Query into a live Query
const {response: liveProducts} = useLiveQuery.TopProducts();
// call the Users Query
const users = useQuery.Users();
return (
<div>
<h1>
Hello Wundergraph
</h1>
<h2>
User
</h2>
<p>
{user === undefined && "user not logged in!"}
{/* If the user is logged in, we're able to use their name and email */}
{user !== undefined && `name: ${user.name}, email: ${user.email}`}
</p>
<p>
{/* Login using GitHub with one function call */}
{user === undefined && <button onClick={() => login.github()}>login</button>}
{/* Logout the user */}
{user !== undefined && <button onClick={() => logout()}>logout</button>}
</p>
<h2>
FakeProducts
</h2>
<p>
{JSON.stringify(fakeProducts.response)}
</p>
{/* Refetch a query on click */}
<button onClick={() => fakeProducts.refetch()}>refetch</button>
<h2>
Set Price
</h2>
{/* call a mutation, overriding the above configured inputs */}
<button onClick={() => {
setPrice({input: {upc: "2", price: randomInt(100)}})
}}>Set
</button>
<p>
{JSON.stringify(price)}
</p>
<h2>
Price Updates
</h2>
<p>
{JSON.stringify(priceUpdate)}
</p>
<h2>
Products LiveQuery
</h2>
<p>
{JSON.stringify(liveProducts)}
</p>
<h2>
OAS Users
</h2>
<p>
{JSON.stringify(oasUsers)}
</p>
<h2>
Countries
</h2>
<p>
{JSON.stringify(countries)}
</p>
<h2>
JSON Placeholder Users
</h2>
<p>
{JSON.stringify(users)}
</p>
</div>
)
}
export const getServerSideProps: GetServerSideProps<Props> = async (context) => {
// for SSR, simply create a new client, no configuration is required
const client = new Client();
// use the client to directly make a request
const products = await client.query.FakeProducts({input: {first: 5}});
return {
props: {
// pass on the data to the page renderer
products: products.status === "ok" ? products.body : null,
}
}
}
const randomInt = (max: number) => Math.floor(Math.random() * Math.floor(max)) + 1
export default IndexPage;

If you're familiar with NextJS and swr, you might recognize where we've got our inspiration from. Some of the APIs are modeled around ideas we've took from the amazing swr framework.

Workflow - How to use NextJS and WunderGraph#

To start a new project, you could use our Quickstart. This gives you a fully functional NextJS + WunderGraph environment.

It's also not much work to start from scratch, use this command to add a WunderGraph environment to your existing NextJS application.

wunderctl init

1. Adding the API dependencies#

Once you have a project up and running, the first step is to add you API dependencies.

const restApi = introspect.openApi({
apiNamespace: "jsp",
source: {
kind: "file",
filePath: "jsonplaceholder.v1.yaml",
}
})
/*
add a GraphQL API using introspection
*/
const countries = introspect.graphql({
apiNamespace: "countries",
url: "https://countries.trevorblades.com/",
})

2. Write a GraphQL Query#

query CountriesAndUsers {
countries { # from the countries GraphQL API
code
name
}
users { # from the json placeholder REST API
id
name
}
}

3. Use in your NextJS Application#

Writing a Query triggers the Code-Generator to generate a fully typesafe client including Hooks for the Operation.

You can now use the generated client to render the data.

const IndexPage: NextPage = () => {
const response = useQuery.CountriesAndUsers();
return (
<div>
{JSON.stringify(response)}
</div>
)
}
export default IndexPage;

4. Continuous deployment#

NextJS and Vercel (the creators of the Framework) encourage continuous deployment to keep the feedback loop short.

WunderGraph is designed from the ground up to support this pattern. You can deploy your API to the Edge on every push, pull request or merge to a specific branch. Any git flow is possible.

Next steps#

If you want to try it out yourself, you can follow our step-by-step Guide.


Product

Comparisons

Subscribe to our newsletter!

Stay informed when great things happen! Get the latest news about APIs, GraphQL and more straight into your mailbox.

© 2022 WunderGraph