Frequently Asked Questions

Product Information & Technical Setup

What is Hygraph and how does it relate to Next.js?

Hygraph is a GraphQL-native headless content management system (CMS) that enables developers and content teams to build modern digital experiences. It integrates seamlessly with frameworks like Next.js, allowing you to leverage server-side rendering, static site generation, and API routes for secure and performant web applications. For more details, visit the Hygraph Next.js CMS integration page.

How do I set up environment variables for a Next.js project using Hygraph and Auth0?

To set up environment variables, copy the .env.local.template file to .env.local. You will need to provide values for AUTH0_CLIENT_SECRET, AUTH0_CLIENT_ID, AUTH0_DOMAIN, SESSION_COOKIE_SECRET, SESSION_COOKIE_LIFETIME, and HASURA_ADMIN_SECRET. These variables are used for authentication and session management. Next.js supports environment-specific files like .env.development or .env.production. For more details, refer to the tutorial on setting up environment variables.

How does authentication work in a Next.js app using Hygraph and Auth0?

Authentication is handled using the Auth0 SDK and Next.js API routes. Sensitive credentials like AUTH0_CLIENT_SECRET are only exposed on the server side. The authentication flow includes login, callback, profile, and logout API routes, each interacting with Auth0 to manage user sessions securely. For a detailed walkthrough, see the Hasura Fit: Setting up NextJs tutorial.

How can I fetch user-specific data securely in Next.js with Hygraph?

By using Next.js's getServerSideProps function, you can ensure server-side execution and privileged access to protected resources. This allows you to check authentication status and fetch user-specific data securely using access tokens from Auth0. For example code and explanation, refer to the tutorial section on creating required pages.

What is the benefit of using server-side rendering and static site generation with Hygraph and Next.js?

Server-side rendering (SSR) and static site generation (SSG) with Next.js provide fast page loads, improved SEO, and secure handling of sensitive data. By combining Hygraph's GraphQL API with Next.js, you can deliver dynamic, personalized content while keeping authentication secrets protected on the server. Learn more in the Why NextJS? section of the tutorial.

Features & Capabilities

What features does Hygraph offer?

Hygraph provides a GraphQL-native architecture, content federation, scalability, and a wide range of integrations. Key features include rapid content delivery, intuitive user interface, robust security, and support for modern development workflows. For a full list, visit the Hygraph Features page.

What integrations are available with Hygraph?

Hygraph integrates with platforms such as Netlify, Vercel, BigCommerce, commercetools, Shopify, Lokalise, Crowdin, EasyTranslate, Smartling, Aprimo, AWS S3, Bynder, Cloudinary, Mux, Scaleflex Filerobot, Ninetailed, AltText.ai, Adminix, and Plasmic. For the complete list, see the Hygraph Integrations documentation.

Does Hygraph provide an API?

Yes, Hygraph offers a powerful GraphQL API for efficient content fetching and management. Learn more at the Hygraph API Reference.

What security and compliance certifications does Hygraph have?

Hygraph is SOC 2 Type 2 compliant, ISO 27001 certified, and GDPR compliant. It offers features like SSO integrations, audit logs, encryption at rest and in transit, and sandbox environments. For more details, visit the Hygraph Security Features page.

Pricing & Plans

What is Hygraph's pricing model?

Hygraph offers a free forever Hobby plan, a Growth plan starting at $199/month, and custom Enterprise plans. For the latest details, visit the Hygraph Pricing page.

Use Cases & Customer Success

Who can benefit from using Hygraph?

Hygraph is ideal for developers, IT decision-makers, content creators, project/program managers, agencies, solution partners, and technology partners. It is especially beneficial for modern software companies, enterprises modernizing their tech stack, and brands scaling across geographies. For more, see the Hygraph Case Studies.

What industries are represented in Hygraph's case studies?

Industries include food and beverage (e.g., Dr. Oetker), consumer electronics (e.g., Samsung), automotive (e.g., AutoWeb), healthcare (e.g., Vision Healthcare), travel and hospitality (e.g., HolidayCheck), media and publishing, eCommerce, SaaS (e.g., Bellhop), marketplace, education technology, and wellness and fitness. See more at Hygraph Case Studies.

Can you share some customer success stories with Hygraph?

Yes. Komax achieved a 3X faster time to market, Autoweb saw a 20% increase in website monetization, Samsung improved customer engagement with a scalable platform, and Dr. Oetker enhanced their digital experience using MACH architecture. Explore more at Hygraph Customer Stories.

Pain Points & Solutions

What problems does Hygraph solve?

Hygraph addresses operational pains (e.g., reliance on developers for content updates, outdated tech stacks, conflicting needs from global teams), financial pains (e.g., high operational costs, slow speed-to-market, expensive maintenance, scalability challenges), and technical pains (e.g., boilerplate code, overwhelming queries, evolving schemas, cache problems, OpenID integration challenges). For more, visit the Hygraph Product Page.

How does Hygraph solve these pain points?

Hygraph provides an intuitive interface for non-technical users, modernizes legacy systems with its GraphQL-native, API-first architecture, ensures consistent branding with content federation, and streamlines workflows to reduce costs and speed up time-to-market. It also simplifies development, query management, and schema evolution, and resolves cache and integration challenges. See detailed solutions at the Hygraph Product Page.

What KPIs and metrics are associated with the pain points Hygraph solves?

Key metrics include time saved on content updates, number of updates made without developer intervention, system uptime, speed of deployment, consistency in content across regions, user satisfaction scores, reduction in operational costs, ROI on CMS investment, time to market, maintenance costs, scalability metrics, and performance during peak usage. For more, see the Hygraph blog on CMS KPIs.

Support & Implementation

How easy is it to get started with Hygraph?

Hygraph is designed for quick onboarding. Customers can sign up for a free account and use resources like documentation, video tutorials, and onboarding guides. For example, Top Villas launched a new project in just 2 months. See Hygraph Documentation for more.

What support and training does Hygraph provide?

Hygraph offers 24/7 support via chat, email, and phone. Enterprise customers receive dedicated onboarding and expert guidance. All users have access to documentation, video tutorials, webinars, and a community Slack channel. For more, visit the Hygraph Contact Page.

How does Hygraph handle maintenance, upgrades, and troubleshooting?

Hygraph provides 24/7 support for maintenance, upgrades, and troubleshooting. Enterprise customers receive dedicated onboarding and expert guidance, and all users can access detailed documentation and the community Slack channel for additional support. See Hygraph Contact for more.

Performance & Security

How does Hygraph ensure optimized content delivery performance?

Hygraph emphasizes rapid content distribution and responsiveness, which improves user experience, engagement, and search engine rankings. Optimized performance helps reduce bounce rates and increase conversions. For more, see the Headless CMS Checklist.

Customer Proof

Who are some of Hygraph's customers?

Notable customers include Sennheiser, Holidaycheck, Ancestry, Samsung, Dr. Oetker, Epic Games, Bandai Namco, Gamescom, Leo Vegas, and Clayton Homes. For more, visit Hygraph Case Studies.

Documentation & Resources

Where can I find Hygraph's technical documentation?

Comprehensive technical documentation is available at Hygraph Documentation.

What kind of content is available on the Hygraph Blog?

The Hygraph Blog features developer tutorials, product updates, and essential guides to content modeling. Visit the Hygraph Blog for more.

Velocity at Scale: Join the Launch of Hygraph’s Latest AI Innovations

Hasura Fit: Setting up NextJs

NextJs is a powerful framework that lets us combine the best of server-side execution and static site generation. Out of the box we get server-rendered content, static resource compilation and API routes ensuring a protected execution environment.
Jesse Martin

Written by Jesse 

Aug 12, 2020
Hygraph, Hasura, Auth0, NextJS, Vercel

#Why NextJS?

NextJs is a powerful framework that lets us combine the best of server-side execution and static site generation. Out of the box we get server-rendered content, static resource compilation and API routes ensuring a protected execution environment.

Why that’s important for us is that we are able to handle our user authentication and Auth0 code in server-side routes where our Auth0 Client secret is protected from our app’s users, while still getting access to really fast pages loading content that doesn’t need to check the server first.

All of the code has been written already in this example repo, but we’ll look at the different parts of the framework to get a better understanding of how it works.

To begin with, you’ll need to provide your own application variables. We’ll be assuming that our code is deployed to Vercel as that is what this tutorial recommends, but the choice is up to you.

#Environment Variables

First, start by creating a copy of the .env.local.template file and rename it to .env.local

cp ./env.local.template .env.local

Returning to the Auth0 console and navigate to your application, you’ll need:

AUTH0_CLIENT_SECRET AUTH0_CLIENT_ID AUTH0_DOMAIN

Additionally, you’ll need to define a random secret for the SESSION_COOKIE_SECRET as well as the SESSION_COOKIE_LIFETIME

Lastly, you’ll need to define HASURA_ADMIN_SECRET which will be used to protect your login if you choose not to use Hasura Cloud.

We define all of these values in a file called “.env.local” because we will define all of the values again in our Vercel admin panel for our project. NextJs supports naming files .env.[environment] as a pattern for mapping specific environment variables to those Node environments. It looks for these files out of the box. The .local prefix is a reminder for us to not push this file into source control (ie. Github).

#Creating the Required Pages in Next

All of the needed pages for the demo exist already in the project repository, but for an explanation, we’ll describe them here.

lib/config

Our config file declares various export values for use throughout our application. Because we are using sever side and client side authentication, we need to define different variables for different contexts. Because we are hosting in Vercel, we need to handle some work-around behaviour to handle our preview URLs (branch deploys) vs our aliased production URL.

if (typeof window === "undefined") {
/**
* Settings exposed to the server.
*/
const url = (production, branch, local) => {
switch (process.env.NODE_ENV) {
case "production":
return production;
break;
case "preview":
return branch;
break;
case "development":
return local;
break;
default:
return local;
break;
}
};
const base = url(
"YOUR_LIVE_VERCEL_APP_ALIAS",
`https://${process.env.VERCEL_URL}`,
"http://localhost:3000"
);
module.exports = {
AUTH0_CLIENT_ID: process.env.AUTH0_CLIENT_ID,
AUTH0_CLIENT_SECRET: process.env.AUTH0_CLIENT_SECRET,
AUTH0_SCOPE: "openid profile",
AUTH0_DOMAIN: process.env.AUTH0_DOMAIN,
REDIRECT_URI: base + "/api/callback",
POST_LOGOUT_REDIRECT_URI: base,
SESSION_COOKIE_SECRET: process.env.SESSION_COOKIE_SECRET,
SESSION_COOKIE_LIFETIME: process.env.SESSION_COOKIE_LIFETIME,
};
} else {
/**
* Settings exposed to the client.
*/
module.exports = {
AUTH0_CLIENT_ID: process.env.AUTH0_CLIENT_ID,
AUTH0_SCOPE: "openid profile",
AUTH0_DOMAIN: process.env.AUTH0_DOMAIN,
REDIRECT_URI: `${window.location.origin}/api/callback`,
POST_LOGOUT_REDIRECT_URI: window.location.origin,
};
}

The URL helper function simply allows us to define which base-url will be used in the various Node environments such as preview, development and local.

Note how we don’t expose our AUTH0_CLIENT_SECRET in our client context, but only in the server? This is part of what makes a framework like NextJS so powerful is the ability to mix contexts like this.

lib/auth0

The auth0 file in our lib creates a new configuration object for the Auth0 SDK. It creates all the required configurations and methods we’ll need to work directly with Auth0, and then exports it for use in other files.

import { initAuth0 } from "@auth0/nextjs-auth0";
import config from "./config";
const auth0Instance = initAuth0({
clientId: config.AUTH0_CLIENT_ID,
clientSecret: config.AUTH0_CLIENT_SECRET,
scope: config.AUTH0_SCOPE,
domain: config.AUTH0_DOMAIN,
redirectUri: config.REDIRECT_URI,
audience: "YOUR_HEROKU_APP_URL",
postLogoutRedirectUri: config.POST_LOGOUT_REDIRECT_URI,
session: {
cookieSecret: config.SESSION_COOKIE_SECRET,
cookieLifetime: config.SESSION_COOKIE_LIFETIME,
storeIdToken: true,
storeRefreshToken: true,
storeAccessToken: true,
},
});
export default auth0Instance;

lib/user

This is highly specific React code and will be covered in the NextJs tutorial. The basic gist of this code is that it implements a React hook to check our /api/me route if the user is still logged-in, if they are, it returns our user data, if not, it redirects a user to a login path and additionally includes some helper state to determine if the browser is still checking for our logged-in status.

pages/api/login

Our login function takes a request to the route /api/login from our website, which then in turn uses our Auth0 lib to send all the client ID and secret information we need to Auth0 along with a secondary parameter called “redirectTo” which is the url that should be called from Auth0’s servers after we succeed or fail to log-in to the app.

import auth0 from "../../lib/auth0";
export default async function login(req, res) {
try {
await auth0.handleLogin(req, res, {
redirectTo: req.headers.referer + "api/callback",
});
} catch (error) {
console.error(error);
res.status(error.status || 500).end(error.message);
}
}

pages/api/callback

Our callback URL handles a request coming FROM Auth0, more specifically, this is a callback that is invoked when a user tries to signup. See the diagram below. hasura-fit-callbacks.png

Our application tries to login, which sends us to Auth0, Auth0 uses a form from their server (in our case) which then sends us back to our callback url that we defined in our login request above. If we had a successful login, that request has tokens corresponding the scopes we requested and whether or not we want to use refresher tokens. Because there can be any number of tokens depending on our settings, the Auth0 library is able to simply take the request coming back from the Auth0 servers, identify which parts are important for our authentication, and save them where they need to go in our browser.

That code looks like this:

import auth0 from "../../lib/auth0";
export default async function callback(req, res) {
try {
await auth0.handleCallback(req, res, { redirectTo: "/" });
} catch (error) {
console.error(error);
res.status(error.status || 500).end(error.message);
}
}

pages/api/me

This route is perhaps the most opaque in terms of understanding the inner workings of the code, but the concept is straight forward. The SDK checks to see if the user still has a valid token to access data from Auth0, if not, it uses the refresh token to generate a new one.

import auth0 from "../../lib/auth0";
export default async function me(req, res) {
try {
await auth0.handleProfile(req, res);
} catch (error) {
console.error(error);
res.status(error.status || 500).end(error.message);
}
}

pages/api/logout

In a near mirror of our callback code, the Auth0 SDK takes a the request to logout and simply removes all the cookies for logging in and ensures no protected content is accessible anymore.

import auth0 from "../../lib/auth0";
export default async function logout(req, res) {
try {
await auth0.handleLogout(req, res);
} catch (error) {
console.error(error);
res.status(error.status || 500).end(error.message);
}
}

We won’t bother outlining the remaining files in NextJs here as they pertain to the presentational layer and edge of out of the scope of this tutorial.

Generally speaking, the actual rendered pages will include a function that follows a similar pattern as the following code snippet.

export async function getServerSideProps({ req, res }) {
// Here you can check authentication status directly before rendering the page,
// however the page would be a serverless function, which is more expensive and
// slower than a static page with client side authentication
const session = await auth0.getSession(req);
if (!session || !session.user) {
res.writeHead(302, {
Location: "/api/login",
});
res.end();
return;
}
const resp = await fetch("https://hasura-fit.herokuapp.com/v1/graphql", {
method: "POST",
headers: {
Authorization: `Bearer ${session.accessToken}`,
},
body: JSON.stringify({
query: `{
sessions {
created_at
workout(stage: PUBLISHED, where: {}) {
title
}
}
}
`,
}),
});
const { data } = await resp.json();
return { props: { sessions: data.sessions, user: session.user } };
}

The specific function here getServerSideProps allows us to guarantee a server-side execution which means privileged access. That’s why we are able to use our authorization header here in the same file as our rendered page because we know this part of the code only runs on the server. This is one of the hidden powers of NextJs.

In the above code, our server will look for a valid session rookie, if it doesn’t find one, it will return us to the login page, otherwise, it will execute a request with our auth token that originally came from Auth0 and is intended for use at Hasura. It will read all the data about my user’s workout session activity, and then, through the remotely joined schema, Hasura will also look up the workout data itself (the title) directly from Hygraph but resolve it to us in one unified server.

One last “complex” query that deserves a special mention is the following code:

fragment Rep on RepMovement {
title
repetition
}
fragment Amrap on AmrapMovement {
title
}
fragment Duration on DurationMovement {
title
duration
}
fragment Circuit on Circuit {
repetitions
movements {
... on RepMovement {
...Rep
}
... on AmrapMovement {
...Amrap
}
... on DurationMovement {
...Duration
}
}
}
query Premium($authed: Boolean!) {
workouts(orderBy: popularity_DESC) {
title
description
popularity
slug
image {
url
}
warmup @include(if: $authed) {
... on RepMovement {
...Rep
}
... on AmrapMovement {
...Amrap
}
... on DurationMovement {
...Duration
}
}
program @include(if: $authed) {
... on RepMovement {
...Rep
}
... on AmrapMovement {
...Amrap
}
... on DurationMovement {
...Duration
}
... on Circuit {
...Circuit
}
}
coolDown @include(if: $authed) {
... on RepMovement {
...Rep
}
... on AmrapMovement {
...Amrap
}
... on DurationMovement {
...Duration
}
}
}
}

This code requests the content for our homepage. In this complex query we define re-usable pieces of query (fragments) to be used in multiple locations of our query body. We also pass in a variable called “authed” which has come from a check to see if the user has a valid session. If it does, it includes the workout data, if it doesn’t, it get’s skipped according to the rule defined in the @include directive’s if argument. This way a user can see the title and basic information about a workout program, but not the full “product” data in this case.

Next: Set up the Serverless Functions

Blog Author

Jesse Martin

Jesse Martin

Share with others

Sign up for our newsletter!

Be the first to know about releases and industry news and insights.