If you need to run WordPress headless, a quality framework is a must-have. However, even with a little help from a modern framework, you may still struggle to preview your content effectively.
That’s where Faust.js comes in. This new framework harnesses the power of Next.js and React, and combines this with convenient post previewing features. With Faust.js, you can view your content before hitting Publish, exactly the same as with a traditional WordPress website.
In this article, we’ll explore why you might want to use Faust.js for your next headless WordPress project. Then we’ll show you how to set up this new framework and build a simple front end. Let’s get started!
Why You Might Want to Run a Headless WordPress Site
The typical Content Management System (CMS) consists of a front end and a back end, and WordPress is no exception. However, it is possible to run WordPress headless.
The ‘head’ refers to the presentation layer, while the ‘body’ is where the content is stored and authored. By removing the front end (head) from the back end (body), you can run WordPress headless.
With a headless project, you’ll continue to use the familiar WordPress dashboard and tools. However, you’re free to design your own front end, independent of WordPress’ usual constraints. This gives you complete control over how your content is displayed.
Creating your own front end may be an exciting prospect, but it isn’t particularly straightforward. Fortunately, there are tools that can perform much of the heavy lifting for you.
Many headless CMS users choose to enlist the help of a tool such as Frontity, the Gatsby framework, or the React-based Next.js. However, traditionally it has been difficult to preview posts and pages on a headless site, even when using a framework. That’s where Faust.js comes in:
This framework is built on top of Next.js and React, and strives to provide a publishing experience that’s consistent with traditional WordPress. To achieve this, Faust.js offers seamless content previews.
Faust.js also uses a GraphQL client. This enables you to query the WordPress WPGraphQL API without having to know the GraphQL queries ahead of time.
In addition, Faust.js provides built-in mechanisms for authenticating your WordPress back end. This makes it easy to build gated content and eCommerce sites with your headless CMS.
How to Create a Headless WordPress Site With Faust.js (In 9 Steps)
Now that we’ve covered what Faust.js is and some of its major benefits, let’s see how you can get started with this framework. Here’s how to create a headless CMS with Faust.js, in nine steps.
Step 1: Prepare Your Development Environment
Before you begin, you’ll need to install Node.js and the Node Package Manager (NPM). You’ll also need a WordPress installation, which you can either host locally or on a web server.
You’ll also be using a few WordPress plugins. First up, the WPGraphQL plugin will transform WordPress into a GraphQL API, ready for your project to consume.
You’ll also need WPE Headless. This plugin provides some extra features that help ensure WordPress functions correctly as a headless CMS. You can download the latest version of this plugin, and then upload it to your WordPress dashboard.
To help you get started with the Faust.js framework, you’ll be using the create-next-app starter project. This generates a bootstrapped Next.js application with all the necessary configurations and files already in place. You can then use this as the basis for your headless Faust.js project.
You can install create-next-app using the npx tool, which is bundled with NPM. In your local Terminal or Command Prompt window, run the following:
npx create-next-app faust-headless-demo
This will create a faust-headless-demo project in your computer’s local users directory. Once this process is complete, the Terminal will prompt you to start your Next.js application using the following commands:
cd faust-headless-demo
npm run dev
Congratulations – you’ve just successfully created a Next.js project! To take a look at this application, head to “http://localhost:3000” in your browser:
You should now see the Next.js starter site. If you encounter an error message, try re-running the npm run dev command, which may resolve the problem.
Step 2: Set Up TypeScript
Faust.js uses TypeScript, which is a typed superset of JavaScript that adds compile-time type checking. This enables you to catch errors at compile time, rather than waiting until runtime. To install TypeScript, run the following commands in your Terminal:
npm install --save-dev @types/react
npm install typescript --save-dev
Now, you need to generate a tsconfig.json file. This file specifies the compiler options that are required to run your project:
npx tsc --init
Once you have TypeScript set up, you’ll need to convert a few JavaScript files to the TypeScript format. Navigate to your local Users directory, which should contain a new faust-headless-demo directory:
Inside faust-headless-demo, open the pages directory. You can now rename the _app.js file to _app.tsx, and replace its contents with the following:
import '../styles/globals.css';
import type { AppProps /*, AppContext */ } from 'next/app';
function MyApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />;
}
export default MyApp;
Next, rename pages/index.js to pages/index.tsx. Your Next.js app is now properly configured for TypeScript.
Step 3: Create a Reusable React Component
At this point, you can put your project to the test by displaying some dummy content. In your local pages directory, create a posts.tsx file:
In this file, you’re going to enter some text. If the following content appears in your browser, you’ll know that your Next.js application is configured correctly:
export default function PostsPage() {
return <h1>The posts page</h1>;
}
In your browser, navigate to “http://localhost:3000/posts”. You should now see this dummy content:
Once you’ve verified your setup, the next step is creating a basic React component. You’ll eventually use this component to display a list of all your WordPress posts.
It’s a best practice to add all of your React components to a dedicated directory. With this in mind, navigate to your project’s root and create a components folder:
Inside this directory, create a post.tsx file. A React component can receive data from the parent component via component props. In this example, you’re going to pass each post’s title and content to the post component.
In TypeScript, you can achieve this by creating an interface to map out the data that you want to pass. Inside your posts.tsx file, add the following:
export interface PostProps {
title: string;
content: string;
}
export default function Post(props: PostProps) {
const { title, content } = props;
return (
<article>
<h1>{title}</h1>
<p>{content}</p>
</article>
);
}
You now have a reusable React component. The next step is using this component in your posts page.
Step 4: Display a List of Posts
To start, open the pages/posts.tsx file. At this point, you’re simply going to provide some fake data, which you’ll display in a list format:
import Post from '../components/post';
const posts = [
{
id: 1,
title:
'Lorem ipsum.',
content:
'nteger porttitor, dui id dapibus euismod, lacus felis tincidunt ante, sit amet eleifend metus enim in orci. Vivamus tincidunt eleifend leo, at scelerisque lacus viverra ac.',
},
{
id: 2,
title: 'Lorem ipsum.',
content:
'In lacinia ipsum et lorem varius, eu porttitor eros porttitor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.',
},
];
export default function PostsPage() {
return <h1>My posts page</h1>;
}
You can create a list of posts by looping through the posts array. This requires you to render a Post component for each item:
import Post from '../components/post';
const posts = [
{
id: 1,
title:
'Lorem ipsum.',
content:
'nteger porttitor, dui id dapibus euismod....',
},
{
id: 2,
title: 'Lorem ipsum.',
content:
'In lacinia ipsum et lorem varius, eu porttitor eros porttitor...',
},
];
export default function PostsPage() {
return (
<div>
<h1>My posts</h1>
{posts.map((post) => (
<Post key={post.id} title={post.title} content={post.content} />
))}
</div>
);
}
Save your changes, and close this file. Then, head over to “http://localhost:3000/posts”:
This tab should now display a list of fake posts. Once you’ve connected Faust.js to the WordPress back end, you’ll use this React component to display a list of your website’s real-life posts.
Step 5: Configure the Faust.js Framework
You’re finally ready to set up the Faust.js framework. To start, install the production and development dependencies by running the following commands:
npm install --save-prod @faustjs/core @faustjs/next
npm install --save-dev @gqty/cli dotenv
Then navigate to your project’s root directory. Inside this folder, create a new faust.config.js file:
You’ll use this file to connect Faust.js to your WordPress back end. You can now enter the following code:
import { config as coreConfig } from '@faustjs/core';
if (!process.env.NEXT_PUBLIC_WORDPRESS_URL) {
console.error(
'You must provide a NEXT_PUBLIC_WORDPRESS_URL environment variable, did you forget to load your .env.local file?',
);
}
/**
* @type {import("@faustjs/core").Config}
*/
export default coreConfig({
wpUrl: process.env.NEXT_PUBLIC_WORDPRESS_URL,
apiClientSecret: process.env.WP_HEADLESS_SECRET,
});
Inside this directory, you’ll also need to create a .env.local file. This will hold all of your environment variables:
Inside .env.local, add the following code. Make sure to replace your-site with your own URL:
NEXT_PUBLIC_WORDPRESS_URL=http://your-site.com
WP_HEADLESS_SECRET=YOUR_PLUGIN_SECRET
You’ll also need to replace YOUR_PLUGIN_SECRET with your site’s headless secret. You can find this information by navigating to Settings > Headless in your WordPress dashboard:
Faust.js will use this headless secret to authenticate its requests to WordPress. This makes it possible to preview draft content on your front end.
Step 6: Configure Your GraphQL Client for Faust.js
Faust.js uses GQty as its GraphQL client. To configure GQty, create a gqty.config.js file in your project’s root directory:
You can now open this file for editing. Inside gqty.config.js, copy and paste the following:
require('dotenv').config();
/**
* @type {import("@gqty/cli").GQtyConfig}
*/
const config = {
react: false,
scalarTypes: { DateTime: 'string' },
introspection: {
endpoint: `${process.env.NEXT_PUBLIC_WORDPRESS_URL}/graphql`,
headers: {},
},
destination: './client/index.ts',
subscriptions: false,
javascriptOutput: false,
};
console.log(`Using "${config.introspection.endpoint}" to generate schema...`);
module.exports = config;
The next step is creating a GQty client, which you’ll be using to query your website’s data. In your project’s root, create a new client directory. Inside this folder, create an index.ts file containing the following code:
import type { IncomingMessage } from 'http';
import { getClient } from '@faustjs/next';
import {
generatedSchema,
scalarsEnumsHash,
GeneratedSchema,
SchemaObjectTypes,
SchemaObjectTypesNames,
} from './schema.generated';
export const client = getClient<
GeneratedSchema,
SchemaObjectTypesNames,
SchemaObjectTypes
>({
schema: generatedSchema,
scalarsEnumsHash,
});
export function serverClient(req: IncomingMessage) {
return getClient<GeneratedSchema, SchemaObjectTypesNames, SchemaObjectTypes>({
schema: generatedSchema,
scalarsEnumsHash,
context: req,
});
}
export * from './schema.generated';
You can now save your changes, and close the index.ts file. Now that you have all the pieces in place, you’re ready to generate the GraphQL schema.
Step 7: Run the Generate Script
The next step is adding a generate script to your package.json file. This script will generate the necessary schema based on the structure of your WordPress site.
To add this script, navigate to your project’s root folder and open the package.json file. You can now add the generate script to the first code block:
{
"name": "fause-headless-demo",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
//Add the following//
"generate": "gqty generate"
},
Before running this script, you’ll need to temporarily enable Public Introspection for your website. In the WordPress dashboard, navigate to GraphQL > Settings. Then scroll to Enable Public Introspection and select its accompanying checkbox:
Click on Save Changes. You can now run the generate script by entering the following command into your Terminal:
npm run generate
This script will create a client/schema.generated.ts file. At this point, you can disable Public Introspection within your WordPress dashboard.
Step 8: Define a FaustProvider Component and Hook
Now, you need to wrap your Next.js application using the built-in <FaustProvider> component. This React Higher-Order Component will provide Faust.js with the context it needs to fetch and cache data.
To achieve this, open your project’s pages/_app.tsx file. You can then replace its contents with the following:
import '../faust.config';
import '../styles/globals.css';
import type { AppProps /*, AppContext */ } from 'next/app';
import { FaustProvider } from '@faustjs/next';
import { client } from '../client';
function MyApp({ Component, pageProps }: AppProps) {
return (
<FaustProvider client={client} pageProps={pageProps}>
<Component {...pageProps} />
</FaustProvider>
);
}
export default MyApp;
You’re now ready to query data from the WordPress back end. You’ll be using the usePosts hook, which provides a standard interface that retrieves a list of posts from the headless WordPress API.
Open the pages/posts.tsx directory and delete all of the boilerplate Lorem Lipsum code. You can then implement the usePosts hook:
import { client } from '../client';
import Post from '../components/post';
export default function PostsPage() {
const { usePosts } = client;
const posts = usePosts()?.nodes;
return (
<div>
<h1>My posts</h1>
{posts.map((post) => (
<Post key={post.id} title={post.title} content={post.content} />
))}
</div>
);
}
The schema file you generated exports a Post type. This means you can use this type to define the Post component props. To accept a Post prop, open the components/post.tsx file and add the following:
import { Post as PostType } from '../client';
export interface PostProps {
post: PostType;
}
export default function Post(props: PostProps) {
const { post } = props;
return (
<article>
<h1>{post.title()}</h1>
<div dangerouslySetInnerHTML={{ __html: post.content() }} />
</article>
);
}
You can specify whether you want to receive the rendered content or raw content. In the above code, you’re opting for rendered content.
Step 9: Connect Faust.js to Your WordPress Website
The final step is creating a link between your data and the Post component. This requires you to add a single line of code to the posts.tsx file:
…
....
….
{posts.map((post) => (
//Add the following line//
<Post key={post.id} post={post} />
))}
</div>
);
}
After making these changes, load “http://localhost:3000/posts” in your browser. You should now see a list of all the posts from your WordPress website:
If your posts don’t appear, terminate the running process by closing your Terminal. Then open a new window and use the change directory command so the Terminal is pointing at your local Faust.js project (for example: cd /Users/username/faust-headless-demo). You can then start the development server (npm run dev), and try refreshing the “http://localhost:3000/posts” page.
Conclusion
Many headless WordPress developers opt to use a framework. However, when it’s time to preview your content, a lot of frameworks force you to log into an external site or view your preview page inside a frame.
Faust.js sets out to provide a consistent, seamless previewing experience. When you set up this framework, you’ll be able to view your content using the familiar WordPress workflow. You’ll also get access to the familiar React and Node.js toolsets.
Do you have any questions about the Faust.js framework? Let us know in the comments section below!
No Comments