Builders https://wpengine.com/builders/ Reimagining the way we build with WordPress. Tue, 04 Jun 2024 17:22:29 +0000 en-US hourly 1 https://wordpress.org/?v=6.5.3 https://wpengine.com/builders/wp-content/uploads/2024/05/wp-engine-favicon-32.png Builders https://wpengine.com/builders/ 32 32 Beta Testing WordPress with Local Blueprints https://wpengine.com/builders/beta-testing-wordpress-local-blueprints/ https://wpengine.com/builders/beta-testing-wordpress-local-blueprints/#respond Tue, 04 Jun 2024 17:20:30 +0000 https://wpengine.com/builders/?p=4810 Start testing the latest WordPress beta quickly with Local Blueprints.

The post Beta Testing WordPress with Local Blueprints appeared first on Builders.

]]>
A new release is on the horizon! 🌅

As with each release, there are countless hours of testing to ensure the overall experience is bug-free and optimized. WordPress 6.6 is targeted to be released on July 16, 2024. Right now, you can help by testing.

Local is the go-to tool to create a WordPress sandbox and effortlessly develop WordPress sites locally, and with Local you can get testing in seconds. Here are a few options to get you started.

Check out this video or continue reading to learn about all the ways to get testing.

Option 1: WP-CLI + Local

If you already have an existing site in Local then you can just upgrade it to the latest beta with WP-CLI. Here is how:

  1. Right-click on your site and choose ‘Open site shell’, which will open your system’s terminal application and automatically launch WP-CLI.
  2. Once WP-CLI is launched then just run this command: wp core update --version=6.6-beta-1
Open WP-CLI in Local

Option 2: Local + WordPress Beta Tester plugin

If you already have a Local site then you can install the WordPress Beta Tester plugin and get the latest beta.

  1. Visit your WordPress dashboard’s Appearance > Plugins, and choose ‘Add New
  2. Search and install the WordPress Beta Tester plugin
  3. Once activated, visit the Tools > Beta Testing area and update the settings to get the latest beta (select the “Bleeding edge” channel and “Beta/RC Only” stream).
WordPress Beta Tester plugin settings screen

Option 3: Local Blueprint FTW!

Save a few clicks and just import our custom Local Blueprint, which comes with everything installed and ready for testing: WordPress Beta Tester plugin with WP 6.6 Beta 1 already installed and the default Twenty Twenty-Four theme activated.

Just click the download button below and drag and drop the downloaded WordPress-Beta-Tester_6.6-Beta-1.zip into your Local app to spin up a new site and get testing!

Drag and drop Blueprint into Local

(Note: the super secret WordPress username and password for the Blueprint is admin.)

Reach out to @WPEBuilders and let us know how you’re using Local and what you’re testing in the latest WordPress 6.6 beta release.

The post Beta Testing WordPress with Local Blueprints appeared first on Builders.

]]>
https://wpengine.com/builders/beta-testing-wordpress-local-blueprints/feed/ 0
ISR Support for Next.js/Faust.js  on WP Engine’s Atlas https://wpengine.com/builders/isr-support-for-next-js-faust-js-on-wp-engines-atlas/ https://wpengine.com/builders/isr-support-for-next-js-faust-js-on-wp-engines-atlas/#respond Mon, 03 Jun 2024 20:39:50 +0000 https://wpengine.com/builders/?p=31636 WP Engine’s Atlas is THE headless WordPress hosting platform.  In this article, I will discuss and guide you through the easy implementation of the latest feature on Atlas:  Support for […]

The post ISR Support for Next.js/Faust.js  on WP Engine’s Atlas appeared first on Builders.

]]>
WP Engine’s Atlas is THE headless WordPress hosting platform.  In this article, I will discuss and guide you through the easy implementation of the latest feature on Atlas:  Support for ISR on Next.js/Faust.js.  By the end of this article, you will have a better understanding of ISR and using Atlas to support it with Next.js/Faust.js

Prerequisites

Before reading this article, you should have the following prerequisites checked off:

  • Basic knowledge of Next.js and Faust.js.
  • An Atlas account and environment set up.
  • Node.js and npm are installed on your local machine.

If you do not and need a basic understanding of Next.js and Faust.js, please visit the docs:

https://nextjs.org/docs

https://faustjs.org/tutorial/get-started-with-faust

What is ISR?

Incremental Static Regeneration (ISR) is a feature introduced in Next.js that allows you to update static content after it has been deployed. Unlike traditional static site generation, which regenerates all pages at build time, ISR enables you to regenerate individual pages on a timed interval as new requests come in. This ensures that your site remains highly performant while still delivering up-to-date content to your users.

Why Use it in headless WordPress?

In headless WordPress, the front end is decoupled from the WordPress backend, often using Next.js and Faust.js to render the website. This architecture offers several advantages, such as improved performance, enhanced security, and greater flexibility in choosing front-end technologies.

However, one challenge with headless WordPress is ensuring that content changes in WordPress are reflected on the front end without sacrificing performance. This is where ISR becomes crucial. By leveraging ISR, you can achieve the following benefits:

Up-to-date Content: ISR allows your site to fetch the latest content updates from WordPress at specified intervals. For example, by setting a revalidation time of 60 seconds, Next.js will check for content updates every 60 seconds. When a user visits a page, the first user will receive stale content, but subsequent requests will serve the updated content, ensuring minimal delay in content updates.

Enhanced Performance: Since ISR updates only the specific pages that need regeneration at set intervals, your site remains fast and responsive. The initial load times are minimized, and only the changed content is updated, reducing the server load and build times.

SEO Benefits: Static pages are highly favored by search engines due to their speed and reliability. With ISR, you maintain the SEO advantages of static generation while ensuring that your content is always fresh and relevant.

Scalability: ISR enables your site to handle large volumes of content efficiently. Whether you’re running a blog with frequent updates or an e-commerce site with dynamic product listings, ISR ensures that your site scales seamlessly.

All those benefits got me stoked!  Let’s get it on our Next.js and Faust.js sites!

Configuring Next.js with Atlas ISR Support

Here are the docs link to the Atlas support for ISR.

In your Next.js project, go to your terminal and install the @wpengine/atlas-next package:

npm install --save @wpengine/atlas-next

This package provides improved support on Atlas.

Once you install it, ensure it is in your project by navigating to your package.json file at the root of your project:

"dependencies": {
   "@wpengine/atlas-next": "^1.1.0",
   "autoprefixer": "10.4.14",
   "eslint": "8.44.0",
   "eslint-config-next": "13.4.9",
   "next": "14.1.2",
   "postcss": "8.4.25",
   "react": "18.2.0",
   "react-dom": "18.2.0",
   "tailwindcss": "3.3.2"
 }

Now that you have verified the proper installation, staying at the root of your project,  modify your next.config.js file like so:

const { withAtlasConfig } = require("@wpengine/atlas-next");


/** @type {import('next').NextConfig} */
const nextConfig = {
 // Your existing Next.js config
};


module.exports = withAtlasConfig(nextConfig);

Faust.js Wrapper

If you are using Faust.js, all you need to do is modify your next.config.js file using the withFaust wrapper:

const { withFaust } = require("@faustwp/core")
const { withAtlasConfig } = require("@wpengine/atlas-next")

/** @type {import('next').NextConfig} */
const nextConfig = {
  // Your existing Next.js config
}

module.exports = withFaust(withAtlasConfig(nextConfig))

Next, we need to verify that it works.  Run your app in dev mode via npm run dev and you should see this output in your terminal:

Stoked!!! It works!!!

Atlas User Portal

We now have ISR set up with the proper configuration. The last steps are to connect our remote repository to Atlas, git push any changes, and observe ISR working in all its cache invalidation glory.

If you have not connected your local project to a remote repository, go ahead and do so.  Atlas supports GitHub, Bitbucket and GitLab.

Once you have connected your remote repository and added all your necessary environment variables, go ahead and build the app. If you have done this with an existing repo, you can git push the change, which will trigger a build.

When the application is finished in the build step, you are on the main page of the Atlas portal.  Navigate over to the Logs subpage:

In the Logs subpage, click the “Show logs” button on the Runtime option:

You should see the same output focusing on line 6 as you did in your terminal to ensure it’s working properly:

Awesome!!! It is implemented and working in runtime.  Now, when you edit or input new content in your WP backend, and then visit the live URL of the Atlas site you just deployed, the ISR should work on the timed interval you set it to like so:

Limitations

Just a note, the docs state that this feature is currently in the Beta phase, which entails:

  1. Functional completeness, offering comprehensive support for Next.js Incremental Static Regeneration.
  2. Ongoing assessment by Atlas Platform teams regarding the feature’s effect on website performance and application scalability.

Conclusion

Implementing Incremental Static Regeneration (ISR) with Next.js and Faust.js on WP Engine’s Atlas platform is a game-changer for maintaining performance and up-to-date content in a headless WordPress setup. By following the steps outlined in this guide, you can leverage ISR to ensure your site remains both fast and current, without the need for full rebuilds. 

The integration with Atlas also simplifies the deployment and management process, providing a seamless workflow from development to production. 
Get stoked on ISR and Atlas to deliver awesome user experiences and keep your site at the edge of web performance and content freshness.  As always, we look forward to hearing your feedback, thoughts, and projects so hit us up in our headless Discord!

The post ISR Support for Next.js/Faust.js  on WP Engine’s Atlas appeared first on Builders.

]]>
https://wpengine.com/builders/isr-support-for-next-js-faust-js-on-wp-engines-atlas/feed/ 0
5 Exciting (and Powerful) WordPress Features https://wpengine.com/builders/wordpress-features/ https://wpengine.com/builders/wordpress-features/#respond Wed, 29 May 2024 15:54:19 +0000 https://wpengine.com/builders/?p=31622 WordPress continues to evolve with various innovative features designed to enhance the user experience and streamline website development. From a revolutionized Font Library to intuitive site icon settings, these updates […]

The post 5 Exciting (and Powerful) WordPress Features appeared first on Builders.

]]>
WordPress continues to evolve with various innovative features designed to enhance the user experience and streamline website development. From a revolutionized Font Library to intuitive site icon settings, these updates cater to novice and experienced users.

WordPress patterns and the efficient List View in the block editor simplify content creation and management. Global Styles and the new theme.json configuration tool provide a unified approach to site customization.

This article explores five exciting WordPress features that enhance and elevate the website building experience for users and developers.

Google Fonts + WordPress: How to Install Them

With WordPress 6.5, the Font Library has transformed font management within the editor, making integrating fonts like Google Fonts easy. Users can now easily add any font from Google Fonts to their WordPress site, enhancing typography with minimal effort. This feature expands creative possibilities, incorporating various fonts into WordPress projects.

Add a Site Icon to Your WordPress Website

In WordPress 6.5, updating your site icon became more intuitive. Users can add or change the site icon directly from the General Settings panel. Navigate to Settings → General to update your site’s visual identity. This enhancement eliminates the need to use the Site Editor or Customizer for this task, making the experience smoother and more efficient.

Understanding List View in the WordPress Editor

The List View in the WordPress block editor is powerful for navigating through layers of content and nested blocks. In the Post and Page Editor or under Appearance > Editor, this feature allows easy selection and arrangement of blocks. It provides a clear, organized view of your content structure, making your editing experience more intuitive and efficient.

WordPress Patterns: How to Create, Edit and Utilize

WordPress patterns are like building blocks, ready to create stylish sections for your pages or posts. By inserting and customizing these patterns, you can quickly create complex layouts, saving you valuable time. Not only do patterns streamline the process, but they also showcase creative block combinations, enhancing your WordPress experience.

Getting Started with Global Styles in WordPress

Global Styles in WordPress simplify site-wide style changes without editing blocks or pages individually. This feature makes it easier for users and theme developers to apply consistent styling across blocks. Theme.json enhances this functionality, offering a unified approach to managing block settings and styles, streamlining the customization of WordPress sites.

The post 5 Exciting (and Powerful) WordPress Features appeared first on Builders.

]]>
https://wpengine.com/builders/wordpress-features/feed/ 0
The New WPGraphQL-IDE https://wpengine.com/builders/the-new-wpgraphql-ide/ https://wpengine.com/builders/the-new-wpgraphql-ide/#respond Mon, 20 May 2024 15:18:02 +0000 https://wpengine.com/builders/?p=31569 Whether you’re a seasoned developer or just starting out with WPGraphQL, you’re likely familiar with its user interface. Now, there’s an exciting update: a new plugin that transforms not just […]

The post The New WPGraphQL-IDE appeared first on Builders.

]]>
Whether you’re a seasoned developer or just starting out with WPGraphQL, you’re likely familiar with its user interface. Now, there’s an exciting update: a new plugin that transforms not just the UI’s look but also enriches it with additional features.

In this article, I’ll guide you through the latest WPGraphQL-IDE plugin, showcasing the enhanced visuals and new functionalities that elevate your experience with WPGraphQL.

Prerequisites

To benefit from this article, you should have experience using WPGraphQL, a WordPress install, and the WPGraphQL plugin installed. If you do not have a WordPress installation, consider using WP Engine’s headless sandbox.

Installation

To install the plugin, navigate to the GitHub repo and download the wpgraphql-ide.zip here

Once you download the plugin, go to your WP Admin and install and activate the plugin on the add new plugins page.  Once you have WPGraphQL and WPGraphQL-IDE installed, you are good to go.

The Old GraphiQL IDE

Before we take a deep dive into the new UI, let’s quickly go over the old one.  When downloading WPGraphQL, the default UI looks like this:

The old IDE features a classic white background. It uses a light color scheme that provides high contrast with dark text, which can be easier to read under certain lighting conditions but can get really hard on the eyes or glare over long periods. 

The layout has sections defined for the query composer, exposing all the data you have in WordPress, the query editor, and the response output. It also has a docs button to expose further documentation needed within the plugin, a history button that enables you to see your past created queries, and a button for screen enlargement.

The New WPGraphQL IDE

The new WPGraphQL IDE is a great addition for developers using WordPress with the WPGraphQL plugin. Its feature-rich and visually appealing interface significantly enhances the user experience.

Aesthetics 👨‍🎨

Upon downloading the WPGraphQL IDE plugin, you will notice you have an option at the top of your screen between the old and new versions:

The plugin allows you to choose between the two IDEs with a simple click. This comes in handy when you want to roll back to using the old version without having to do any heavy lifting.  In the next version, the WPGraphQL team will move this to the settings section so one is hidden and the other is exposed.

This is what the new version looks like when you click and choose it:

The first feature to notice is the new dark theme, which gets me super stoked!!! Utilizing shades of dark blue and gray, this theme is less straining on the eyes, particularly beneficial in low-light conditions. This makes it an excellent option for those spending extended hours coding. Moreover, dark mode not only reduces eye strain but also provides the interface with a modern and sleek appearance, significantly enhancing the aesthetic user experience.

The new IDE maintains a similar layout but improves visual separation through the use of color contrasts and shaded panels. This helps in distinguishing between different sections of the interface more clearly.

Enhanced typography with better spacing and font choices is implemented, contributing to a more pleasant visual and reading experience.

Features of the WPGraphQL IDE

The new features in the IDE are more stylized with great-looking icons and button designs.  Let’s dive into what they do and the capabilities of each.

All Access IDE Drawer 🚀

One convenient feature (And one of my favorites of this) the new WPGraphQL IDE contains is the IDE drawer.  You have access to the IDE on every page of the WP admin, the block editor UI, as well as the actual public-facing site.  All you need to do is just click on the rocket emoji 🚀 next to the GraphQL IDE option on the toolbar.   It is exposed anywhere the WP Admin bar is present.  This will get ya’ll stoke to not have to go back into the actual IDE page and just access it anywhere!

Here is a sample of the drawer being accessed on your frontend site:

Open Settings Dialog ⚙️

On the bottom left-hand corner of the IDE, you have a cog icon.  When clicked, it will reveal your settings:

The 3 settings you can control from this card are: 

  • Persist headers – This setting allows you to save custom HTTP headers across sessions. Turning it “On” will retain headers like authentication tokens when the IDE is reloaded. It’s recommended to use this feature only if you trust the device you’re working on, as retaining sensitive headers can pose a security risk if accessed by others.
  • Theme-This provides options to adjust the visual theme of the IDE interface to either match the system theme automatically or explicitly set it to a light or dark theme. This helps customize the look of the IDE according to your preference or environmental conditions (e.g., using dark mode at night to reduce eye strain).
  • Clear storage – This action removes all locally stored data in the IDE, such as cached responses, saved queries, and headers. It’s useful for starting fresh or troubleshooting issues related to corrupted or outdated local data.

Short Keys 🍏

When you click on the command icon, you will see a card with a cheat sheet for your short keys to shortcuts for certain functions.

Cmd + F: Search in editor—This shortcut opens a search input on the page, allowing you to type what you are looking for in the editor, as the image shows below.

Cmd + K: Search in documentation—This shortcut opens a search input when you are in the Docs pane, allowing you to quickly type and find the specific document you are looking for.

Cmd + Enter: Execute query—This shortcut allows you to execute the query you created in the query pane to get the JSON response.

Ctrl + Shift + P: Prettify editors—This shortcut allows you to automatically format the code written in the query editor to make it more readable and aesthetically pleasing. It ensures that your indentation, spacing, and line breaks are clean and enhances readability. The previous image shows a query that was prettified.  

Ctrl + Shift + M: Merge fragment definitions into operation definitions. In GraphQL, fragments are reusable pieces of query logic that can be included in multiple query or mutation operations. They help avoid redundancy in your codebase, making your queries easier to read and maintain.  

When you use this shortcut, the WPGraphQL IDE automatically integrates all the fragment definitions you have created into the main operation in which they are used. The merge will identify all fragments and integrate and merge these fragments directly into the operation’s definition, replacing the fragment spread with the actual definitions. This helps in viewing or debugging the operation as a single cohesive unit without the need to look up fragment definitions.

A sample fragment:


When using the shortcut, it will merge the PostFields fragment directly into your query, replacing the fragment spread with the actual defined fields in the fragment.

Ctrl + Shift + C: Copy query—This is a quick way to copy your query and paste it in your front end or wherever you want to paste it.

Ctrl + Shift + R: Re-fetch schema using introspection — A quick way to re-fetch the GraphQL IDE’s schema and keep it current.


Just a note, the Prettify, Copy, and Merge shortcuts also are available to you in the middle query pane as an icon pointed out in this image:

Notice the last icon, which is a link. This feature allows you to share the actual query document page with an authenticated user in your WP Admin. It’s awesome when collaborating with your team.

Re-fetch 🔄

When clicked, the refresh icon ensures that the GraphQL IDE’s schema always reflects the current state of the server schema. This aids accurate query development and troubleshooting by adding up-to-date changes to types, fields, or adjusted relationships.

Help 🆘

No, it’s not the Beatles’ fifth studio album (although it’s a great one!)… When clicked, it reveals a structured and comprehensive help menu designed to assist users at various levels of familiarity with WPGraphQL. From the beginner level all the way to joining the Discord server, it is a fast and convenient way to get the references you need for the level you are looking for.

GraphiQL Explorer 🗂️

The file icon, when clicked, reveals your explorer that exposes in a list format the array of WordPress-specific types and fields that can be queried via GraphQL.  This gets devs stoked by easily selecting them from this list and building out their queries much easier.

Docs 📘

When clicked, the book icon reveals the docs. This serves as a gateway to the documentation viewer within the IDE. This tool is essential for developers as it provides detailed insights and navigable descriptions of the GraphQL schema used within your WordPress setup. 

The documentation provides insights on root types, all schema types, detailed type information, and additional types. 

Conclusion

The WPGraphQL IDE plugin is a tool that enhances the developer experience when using and interfacing with its visuals and features. I touched on the plugin’s updated features. I encourage you to download the plugin and get stoked about its new look and capabilities!

There are more changes and updates to come. So as always stay tuned! We also would love to hear your feedback, thoughts, and projects you are doing in headless WordPress so hit us up in our Discord and the new WPGraphQL Discord!

The post The New WPGraphQL-IDE appeared first on Builders.

]]>
https://wpengine.com/builders/the-new-wpgraphql-ide/feed/ 0
Headless WordPress and Next.js 14: Core Competencies in App Router https://wpengine.com/builders/headless-wordpress-and-next-js-14-core-competencies-in-app-router/ https://wpengine.com/builders/headless-wordpress-and-next-js-14-core-competencies-in-app-router/#respond Mon, 22 Apr 2024 17:09:39 +0000 https://wpengine.com/builders/?p=31543 The App Router in Next.js 14 allows you to use React’s latest features, such as Server Components and Streaming. Combining this with headless WordPress can be daunting, especially with the […]

The post Headless WordPress and Next.js 14: Core Competencies in App Router appeared first on Builders.

]]>
The App Router in Next.js 14 allows you to use React’s latest features, such as Server Components and Streaming. Combining this with headless WordPress can be daunting, especially with the latest features within the framework and how the rendering methodology fits together in certain use cases.

In this article, I will guide you through a series of code challenges. I encourage you to try these yourself and if you get stuck, the answers are in the GitHub repository. At the end of this article and code challenge, you will gain knowledge of the core features in Next.js 14 using headless WordPress.

If you prefer the video format of this article, please access it here:

Pre-Requisite Knowledge

To get the most out of this article, you should have a basic understanding of HTML, CSS, React, and Next.js. If you need to brush up on your React skills, check out the React Foundations Course, which will introduce you to the fundamentals.

If you need to brush up on basic Next.js App Router methodology, please refer to my article here before reading this article.

The addition of the App Router to Next.js and the advent of React Server Components have ushered in a significant paradigm shift. In the past, devs using Next.js may have considered whole pages to be either SSG(Statically Generated), SSR(Rendered on the Server), or ISR(Incremental Static Regeneration).

Now, however, they’re most often thinking of their apps in terms of:

  • “Where should this render?” (server, client, or both)
  • “When should this render?” (build time, runtime, or stream whenever the server sends the response).

By the end of this, you’ll end up with your own Next.js 14 project that contains these pages:

  • /static-rendering
  • /dynamic-rendering
  • /streaming
  • /client-side-rendering

(A side note: I made a Navbar just to make it easier to navigate between pages, as you will see in the repo. However, you do not have to make one as you follow along since I will not go over the creation of one and the Next.js Link component.)

Here is the link to the finished repository for this article:

https://github.com/Fran-A-Dev/devrel-nextjs14-corecomp

Nested layouts and Partial rendering

Nested layouts are a new feature in the App Router. Let’s start with it.

Create a root layout that applies to the entire app. It should render this markup:

<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8" />
 <title>DevRel Headless WP Core Competencies</title>
</head>
<body>
 <!-- Site content goes here -->
</body>
</html>

Replace <!-- Site content goes here --> with the children passed in.

Following that, create /dashboard/purchases and /dashboard/account routes with a simple div element rendered on each.

Once you have those finished, create a layout that applies to all routes nested under the /dashboard/.

It should render a sidebar that contains <Link /> components that point to the Purchases (/dashboard/purchases) and Account (/dashboard/account) pages.

Remember, if you get stuck during these challenges, you can refer to the finished repo. Here are links to the specific docs for this section:

https://nextjs.org/learn/dashboard-app/creating-layouts-and-pages

https://nextjs.org/learn/dashboard-app/navigating-between-pages

Image Component

Images are an important part of any website. In Next.js, its Image component extends the HTML <img> tag with features for auto-image optimization using a variety of props and configurations.

In this section, let’s utilize the image component to render an AVIF. An Avif is a powerful open-source, free file format that encodes AV1 bitstreams in the High Efficiency Image File Format (HEIF) container.

First, copy this image into your project:

https://videomentions.com/mic-and-headphones.avif

Then, on the Account page, render this image at the top using Next.js’ Image component. Make sure you specify the image and height to guard against Cumulative Layout Shift (CLS).

Below the image, render details and summary elements that display the following questions and their answers (it’s up to you to answer them 😊):

  • Does a simple <img> tag get rendered, or something else?
  • Is the primary image still in AVIF format, or something else?
  • Are srcset and sizes attributes defined to reference other sizes of this image? If so, explain how they work to serve responsive images.
  • Does the image leverage native lazy loading?

Inspect the image markup that gets rendered on the front end and take note of what you see.

The docs to this section: https://nextjs.org/learn/dashboard-app/optimizing-fonts-images#why-optimize-images

You should have something that looks like this now:

Server Components and Data Loading

React Server Components (RSCs)are components that allow you to write UI that can be rendered and optionally cached on the server side.  In Next.js 14 and its new App Router, the rendering work is further divided by route segments to enable streaming and partial rendering. The data loading is also done on the server.

Static Rendering

In this section, let’s utilize an RSC that does the data loading and rendering on the server. The goal is to create a full static page that can be cached on a CDN in a server component.

First, create a new /static-rendering route segment in the root of the App directory. Inside this route segment, include the declaration for a server component.

Then, await a fetch call to the /graphql endpoint associated with your headless WP backend to get the most recent 10 blog posts. Make a request for the databaseId, title, date and excerpt. Use raw fetch API for this and define the WPGraphQL requests in a template literal.

With the data returned, render a list of posts to the page. For good HTML semantics, represent each post as a <article> tag.

Time-Based Revalidation

This fully static page poses a problem, though. When a new blog post is published, this page will be out-of-date; it’ll still show the same list of posts that existed at the time it was generated.

Please use the stale-while-revalidate method here or SWR. The page should be invalidated once every 30 minutes to display accurate, fresh data. You can also test this out by doing a 10-second interval, changing your data in WordPress, then hitting your page again, waiting 10 seconds, then hitting it again. It should look like this:

The time-based method is great, but what if you have a use case where you need up-to-the-minute, close-to-real-time data? Next.js does have a way to do this. On-demand Revalidation allows you to invalidate your data on demand by path.

If you would like to add this method to the file instead of time-based, please free to do so. I left this method out of the repo. Currently, Atlas does not support on-demand revalidation but is working on adopting support for it soon!

Here are the docs for this section:

Static Rendering: https://nextjs.org/learn/dashboard-app/static-and-dynamic-rendering

Revalidation Techniques: https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating#revalidating-data

https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating#on-demand-revalidation

Dynamic Rendering

Dynamic Rendering or Server-Side Rendering is content rendered on the server for each user when the user visits the page at each request. This rendering method is beneficial if you need real-time data, user-specific content such as a dashboard, or access to information that can only be known at request time, such as cookies.

In this section, we will utilize this method to display relative date strings on a page, such as “Ten minutes ago,” “Three months ago,” etc.

First, create a new /dynamic-rendering route segment in the App directory. Copy your page component from the /static-rendering route and paste it in as the starting point for the /dynamic-rendering page component.

Next, use the unstable_noStore utility to opt out of static rendering and make the page dynamic (rendered on the server at request time). Docs: https://nextjs.org/docs/app/api-reference/functions/unstable_noStore

Let’s use the date-fns Use the NPM package to format dates as relative date strings (“Ten minutes ago,” “Three months ago,” etc.), as shown in this example.

If you have followed these steps correctly, you have now created a dynamic page that will always display up-to-date relative date strings to users. Stoked! It should look like this:

There are a few considerations in this section. Dynamism is costly since it requires more load on the server and is less performant. This is no longer a cacheable static page. It will hit the server on each request. Sometimes, though, it is worth it, depending on your use case. The date-fns library will not be included in the client-side bundle since this is being used server side.

Streaming and React Suspense

Streaming is a data transfer technique that allows you to break down a route into smaller “chunks” and progressively stream them from the server to the client as they become ready.

In this section, let’s use streaming to grab data from WPGraphQL and a random API endpoint that is not from WordPress. Docs:https://nextjs.org/learn/dashboard-app/streaming

The first thing we need to do is choose a random API endpoint. You can use any API endpoint that returns JSON data. For this example, I am going to use JSON server, an NPM package that allows you to run a local server and gives you an endpoint on whatever port you want to watch it at.

If you decide to use the JSON server method, you will need to create a file to house the JSON. For this article, I created a folder in the root of the project and just added my JSON there:

(Just a reminder, in choosing this method, you will need to run the command on another terminal to spin up the JSON server)

If you do not feel like using that, you can use any common one. I find the Rick and Morty GraphQL API to be a reliable one that many developers use. With this method, you can fetch the data right from the endpoint.

 Next, create a new route segment called /streaming. Copy the /dynamic-rendering page component into it as a starting point.

Remove the data fetching from the page component and add these two functions to the file:

https://gist.github.com/Fran-A-Dev/678ebe8a4e0affb80ab253402dcb88bc

Notice the “Simulate 3 seconds of network latency” line within the fetchStarWarsCharacters() function. This will be the data that will lag behind the WordPress data. Because this network latency exists, let’s opt for a streaming approach where we’re going to render our page immediately, show a loading placeholder, and then stream in the markup from these components when they’re ready using React Suspense.

Once that is all done, create a custom loading.jsx file within the root of the application and add whatever markup and style you want to it. When you create that file, import it into the page component of the streaming route segment and pass that into the Suspense component like this: <Suspense fallback={<Loading />}>

Ensure that within the page.jsx for this component, the post list, and characters list pop into the UI at the same time, regardless of which one took longer.

Stoked!!! We now have a page that loads as quickly as possible with the parts of the page that rely on more expensive queries being streamed in. It should look like this:

Client-Side Rendering

Client Components allow you to write interactive UI that is prerendered on the server and can use client JavaScript to run in the browser. Now, this was the default rendering method in React.js before server components. However, with Next.js 14, you now have to declare a component to be client-side with the "use client" directive in a file.

For this section, let’s build a dynamic page that grabs the github-username query string parameter in the URL, fetches that user’s public SSH key, and displays it on the page. This data fetching and rendering will take place entirely on the client– none of it on the server.

First, create a new /client-side-rendering route segment. Inside that route segment, create a simple page component that renders, then renders the <GitHubSSHKey /> component that we’ll create next.

Now, within this same route segment, create a GitHubSSHKey component. Include the "use-client" directive to mark it as a client component. Inside of this component, render the custom loading component we made in the previous section. Here are the docs: https://nextjs.org/docs/app/building-your-application/rendering/client-components

Following that, we need to access the value of the github-username query string parameter as described in the docs here. We can use the value of the github-username to make a fetch request like this to grab the user’s SSH key:

const response = await fetch(`https://github.com/${username}.keys`);
const sshKey = await response.text();

Once the request resolves, store the SSH key in state and trigger a re-render to replace your loading skeleton with this:

<h2>Public SSH key for {username}:</h2>
<p>{sshKey}</p>

Now, just add a query parameter to the URL with the github-username key and assign it the username and SSH key you want to grab. I used Kellen Mace’s.

Stoked!!! We have now implemented a client component. Something to keep in mind is that you can render a client component from a server component which we just did here. However, the other way around will not work. You can’t have a client component that renders a server component.

Conclusion

Next.js 14 is the latest version of the most used meta framework on top of React. It introduces new ways to handle data, create routes and files as well as rendering methods.  We hope you have a deeper understanding of how its core competencies work together.

Stay tuned for more Next.js 14 and headless WordPress content coming soon!!

As always, stoked to hear your feedback and any questions you might have on headless WordPress! Hit us up in our Discord!

The post Headless WordPress and Next.js 14: Core Competencies in App Router appeared first on Builders.

]]>
https://wpengine.com/builders/headless-wordpress-and-next-js-14-core-competencies-in-app-router/feed/ 0
WPGraphQL Smart Cache Updates: Clarifying The Cache https://wpengine.com/builders/wpgraphql-smart-cache-updates-clarifying-the-cache/ https://wpengine.com/builders/wpgraphql-smart-cache-updates-clarifying-the-cache/#respond Fri, 05 Apr 2024 15:39:15 +0000 https://wpengine.com/builders/?p=31534 WPGraphQL Smart Cache is a plugin in the WPGraphQL ecosystem that provides on-demand invalidation of cached WPGraphQL data. This means that you can leverage caching solutions like a persistent object […]

The post WPGraphQL Smart Cache Updates: Clarifying The Cache appeared first on Builders.

]]>
WPGraphQL Smart Cache is a plugin in the WPGraphQL ecosystem that provides on-demand invalidation of cached WPGraphQL data. This means that you can leverage caching solutions like a persistent object cache or a network cache such as Varnish for great performance and automatically invalidate the cached data whenever data changes in WordPress to ensure that cached data stays fresh.

In this article, I will go over in detail the new updates to the plugin.

If you prefer video format, please reference the video here.

Prerequisites

To benefit from this article, you must have a fundamental understanding of headless WordPress, WPGraphQL, and Smart Cache.  

If you are not familiar with the basics and functionality of WPGraphQL Smart Cache, please refer to my article as well as the WPGraphQL article here.

You will also need a supported host since this requires a specific implementation within your hosting platform to work. WP Engine is one host that supports this out of the box. If you do not have a WP Engine server, you can get a free sandbox here.  

Jason Bahl also has a gist to make it work with Lightspeed hosts: https://gist.github.com/jasonbahl/d777c7229bad5142211a58ed00da6598

WPGraphQL Smart Cache

Two of the most difficult things in Web Development are naming things and cache invalidation.  Luckily, the creation of WPGraphQL Smart Cache has made it easier.  Since this plugin’s beginnings two years ago, it has some updates to go over. Let’s dive into them.

What’s New

The UI within WP Admin when downloading the plugin clarifies the settings more to improve the visual hierarchy and organization.


When you download the plugin, navigate over to the GraphQL > Settings > Cache page on the left-hand side of the hamburger menu and you should see this:

Network Cache

The first setting is the Network Cache.  Network cache refers to a system that stores copies of content close to users, typically within a network infrastructure like CDNs or web servers, to reduce latency and server load. When a user requests content, the network cache provides the data from the nearest cache node instead of fetching it from the origin server. This process speeds up content delivery, decreases the load on the origin server, and improves the overall user experience by providing quicker access to the content.

This setting influences how the plugin interacts with network cache clients like Varnish. For instance, the Cache-Control max-age setting specifies how long (in seconds) the network should consider the cached data fresh for GraphQL requests. By setting a proper max-age, the plugin leverages the built-in caching layers of the hosting environment, reducing the load on the WordPress server.

If you use a max-age of 0 , requests will not be cached. This could be necessary for scenarios where data must be real-time or near-real-time, and any caching could result in stale data being served to the client.

However, this should be used with caution for these reasons:

Performance Impact: Without caching, each request for data will hit the WordPress server directly, which can lead to increased load times for the client and higher resource utilization on the server. This defeats the primary benefit of caching, which is to improve performance by reducing the load on the server.

Scalability Concerns: In high-traffic scenarios, bypassing the cache could potentially overload the server with requests that could have been served from the cache, leading to scalability issues.

Increased Costs: More server resources to handle uncached requests can lead to increased operational costs, especially if you are using a hosting service that charges based on resource usage.

Object Cache

Object cache is a mechanism that stores the results of complex data queries in memory to be quickly retrieved on subsequent requests, without the need to re-query the database each time. This is particularly useful for dynamically generated content that does not change between user requests, as it can significantly reduce database load and improve website performance.

Object cache should ideally be considered as a secondary layer of caching when network cache cannot be used. Network cache serves a broader scope by caching entire HTTP responses, often at the edge closer to the user, and is more efficient for content that is shared across many users. Object cache, being closer to the application layer, is suited for pieces of data unique to the application logic that might not be as effectively cached by network layers.

In scenarios where the network cache like Varnish is not available or suitable—perhaps due to highly dynamic content that changes frequently or personalized content that is unique per user—object caching becomes beneficial. It offers granular control over how individual pieces of data are stored and retrieved. However, because it typically resides on the same server as the application, it does not provide the same scalability benefits as network caching and can increase the load on the server if not managed correctly. Hence, it’s recommended to leverage network caching first, where possible, to maximize the efficiency and scalability of content delivery.

The new settings here would allow users to enable object caching and define the time-to-live (TTL) for the cached objects, which means how long the data remains in the cache before it’s considered stale and refreshed.

Debugging

Developers are always stoked to have tools for easier debugging.  Now they are available in Smart Cache.

Log Purge Events

This specific setting within the debugging section gives users the option to track when and why cache purges happen. This could be critical for understanding patterns in cache invalidation and ensuring the cache behaves as expected.

Purge Now

This option provides a manual trigger for users to clear the cached GraphQL Queries. This feature is useful when changes have been made that should be reflected immediately, bypassing the default expiration time.

Did You Purge The Cache

This field confirms whether a cache purge has been successfully triggered and completed. Knowing the last purge timestamp can be helpful in coordinating cache invalidation with site updates or troubleshooting issues.

Conclusion

The WPGraphQL Smart Cache plugin is a tool that supports and solves cache invalidation and caching optimally for WPGraphQL queries. 

I touched on some updated features of the plugin. I encourage everyone to dive into the repo, as mentioned, to get their hands dirty and explore all the other awesome features in this plugin.

There are more changes and updates to come. So as always stay tuned! We also would love to hear your feedback, thoughts, and projects you are doing in Headless WordPress so hit us up in our Discord!

The post WPGraphQL Smart Cache Updates: Clarifying The Cache appeared first on Builders.

]]>
https://wpengine.com/builders/wpgraphql-smart-cache-updates-clarifying-the-cache/feed/ 0
Custom Content in Headless WordPress Using Advanced Custom Fields and WPGraphQL https://wpengine.com/builders/custom-content-in-headless-wordpress-using-advanced-custom-fields-and-wpgraphql/ https://wpengine.com/builders/custom-content-in-headless-wordpress-using-advanced-custom-fields-and-wpgraphql/#respond Wed, 27 Mar 2024 16:01:27 +0000 https://wpengine.com/builders/?p=31523 Creating custom content types is a prevalent part of many modern, content-rich headless WordPress sites. By defining custom content types, developers can structure their data in a way that best […]

The post Custom Content in Headless WordPress Using Advanced Custom Fields and WPGraphQL appeared first on Builders.

]]>
Creating custom content types is a prevalent part of many modern, content-rich headless WordPress sites. By defining custom content types, developers can structure their data in a way that best suits their specific requirements, ensuring consistency and efficiency in content management. On a headless WordPress site, this can be done easily using Advanced Custom Fields to design the content structure and WPGraphQL to query data.

Introducing Advanced Custom Fields (ACF)

While WordPress provides built-in support for standard content types such as posts and pages, Advanced Custom Fields (ACF) allows users to define custom content types and fields for WordPress websites. This plugin enables developers to visually create custom fields for posts, pages, custom post types, and taxonomy terms. These custom fields can store a wide range of data types, including text, images, files, and more, making it a popular tool for tailoring WordPress content to specific needs.

Begin by defining custom post types and fields using the ACF interface within the WordPress admin dashboard. You can create any type of custom post type and add a few fields to it. Then, add some example data in the WordPress admin.

Setting Up GraphQL in WordPress

To expose WordPress data via GraphQL, we’ll utilize the WPGraphQL plugin. WPGraphQL provides a schema and endpoints to query WordPress data using GraphQL syntax.

WPGraphQL serves as the bridge between WordPress and modern frontend frameworks by exposing WordPress data via a GraphQL API. With WPGraphQL, developers can query WordPress content with precision, retrieving only the data they need for a particular request.

We will need to install two plugins to access ACF data using GraphQL queries: the WPGraphQL plugin and the WPGraphQL for ACF plugin.

Accessing ACF Data with GraphQL Queries

Settings to Make Data Accessible

Notably, you will need to do two things to proceed with accessing ACF data. First, check the Enable Public Introspection box in GraphQL’s settings. Then, on each created Post Type’s page in ACF, click the slider for Advanced Configuration. Select the furthest right tab titled GraphQL and enable the Show in GraphQL slider.

GraphQL Queries

Let’s dive into using GraphQL queries to retrieve ACF data from WordPress.

For example, here is a query that fetches a list of products along with their ACF fields:

{
  products {
    edges {
      node {
        id
        title
        acfFields {
          productName
          productDescription
          productImage {
            sourceUrl
            altText
          }
        }
      }
    }
  }
}

Let’s break down what each part of the query is doing:

  1. products: This is the root field of the query, indicating that we want to retrieve data related to products.
  2. edges: This is a connection type used in WPGraphQL to represent a list of items with pagination information. It’s commonly used when querying data from a list or collection.
  3. node: Within each edge, there is a node representing a single product item. This is where the actual data for each product resides.
  4. id: This field requests the unique identifier (ID) of each product. IDs are typically used to uniquely identify each item in a collection.
  5. title: This field requests the title of each product. Titles are common pieces of information associated with content items in WordPress.
  6. acfFields: This field requests custom fields associated with each product. In this case, it’s specifically asking for fields created using the Advanced Custom Fields (ACF) plugin.
  7. productName, productDescription, productImage: These are custom fields defined in ACF for products. The query requests data for each of these fields, including the product name, description, and image.
  8. sourceUrl, altText: These are sub-fields of the productImage field, requesting the source URL (i.e., the URL of the image) and alt text (i.e., the alternative text for the image) respectively.

For your own queries, you can replace the values such as productName, productDescription, and productImage with your own ACF field names.

Integrating ACF Data in a React App

Once we have our GraphQL query, we can integrate it into a React web application. This React component fetches the product data using the previous GraphQL query and displays the list of products.

import React from 'react';
import { useQuery, gql } from '@apollo/client';

const GET_PRODUCTS = gql`
{
  products {
    edges {
      node {
        id
        title
        acfFields {
          productName
          productDescription
          productImage {
            sourceUrl
            altText
          }
        }
      }
    }
  }
}
`;

const ProductList = () => {
  const { loading, error, data } = useQuery(GET_PRODUCTS);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error :(</p>;

  return (
    <div>
    {data.products.edges.map(({ node }) => (
      <div key={node.id}>
        <h2>{node.title}</h2>
        <p>{node.acfFields.productName}</p>
        <p>{node.acfFields.productDescription}</p>
        <img src={node.acfFields.productImage.sourceUrl} alt={node.acfFields.productImage.altText} />
      </div>
    ))}
    </div>
  );
};

export default ProductList;

Let’s take a look at how this React component works.

GraphQL Query Definition

The GET_PRODUCTS constant defines a GraphQL query using the gql tag template literal. This query requests data for products, including their IDs, titles, and custom fields (productName, productDescription, and productImage), from the headless WordPress backend.

ProductList Component

Inside the component, the useQuery hook is used to execute the GraphQL query defined in GET_PRODUCTS. It returns an object containing loading, error, and data properties. If the query is still loading (loading is true), the component renders a loading message (<p>Loading...</p>). If there is an error during the query execution (error is not null), the component renders an error message (<p>Error :(</p>). If the query is successful and there are no errors, the component renders a list of products.

The list of products is rendered using the map function on data.products.edges, which represents an array of product nodes. For each product node, a <div> element is rendered with the product’s title, productName, productDescription, and productImage (including source URL and alt text) displayed.

Conclusion

Many headless WordPress sites require the ability to create and query for custom content types. Leveraging Advanced Custom Fields (ACF) for content customization and WPGraphQL for seamless data retrieval offers a powerful solution for building flexible and customizable websites.

The post Custom Content in Headless WordPress Using Advanced Custom Fields and WPGraphQL appeared first on Builders.

]]>
https://wpengine.com/builders/custom-content-in-headless-wordpress-using-advanced-custom-fields-and-wpgraphql/feed/ 0
Post Previews in the App Router with Faust.js for headless WordPress https://wpengine.com/builders/post-previews-in-the-app-router-with-faust-js/ https://wpengine.com/builders/post-previews-in-the-app-router-with-faust-js/#respond Fri, 15 Mar 2024 16:10:53 +0000 https://wpengine.com/builders/?p=31512 Post previews in WordPress allow users to view content exactly as it will appear on the live site before it is published. This feature is essential for authors, editors, and […]

The post Post Previews in the App Router with Faust.js for headless WordPress appeared first on Builders.

]]>
Post previews in WordPress allow users to view content exactly as it will appear on the live site before it is published. This feature is essential for authors, editors, and administrators to review and approve posts, ensuring that formatting, images, and layouts are correct and meet the intended design and content standards. Post previews are accessible through the WordPress editor, where a “Preview” button is available.  

Getting this to work in a headless setup is difficult.  Luckily, Faust.js does this out of the box.

This article delves into the mechanics of post previews within the experimental app router example project of Faust.js. We will explore the implementation of Post Previews in traditional WordPress, examine the integration with Faust.js’s App Router, and dissect the underlying processes within the Faust.js framework itself.   

Prerequisites

To fully comprehend and gain insight from this article, you should have a foundational understanding of the App Router, including its naming conventions and its directory and file hierarchy. If you are not yet familiar with these concepts, please reference my previous article on the subject before proceeding with this one.

Post Previews in Traditional WordPress

Before we discuss how Faust.js with the App Router does Post Previews, let’s take a look at WordPress’ traditional monolithic architecture approaches it under the hood:

Draft Saving: When you’re working on a post in WordPress, it automatically saves your changes as a draft. This draft is stored in the WordPress database in the wp_posts table, with a post status of ‘auto-draft’ or ‘draft’.

Preview Request: When you click the “Preview” button, WordPress initiates a request to generate a preview of the post. This request includes a query parameter (usually preview=true) that tells WordPress this is a preview request.

Post Revision Creation: To handle the preview, WordPress creates a post revision. This is a copy of your post at that moment, also stored in the wp_posts table, but with a post type of ‘revision’. This ensures that your current edits, even if not saved as a draft, are captured in this revision.

Preview Link Generation: WordPress generates a preview link that includes a nonce (a one-time use security token) to ensure the preview request is valid. This link points to the post URL but with additional query parameters that instruct WordPress to load the revision instead of the published content.

User Role and Permission Check: When the preview link is accessed, WordPress checks the user’s role and permissions to ensure they have the right to view the preview. This step is crucial for content security and integrity.

Rendering the Preview: If the user has the appropriate permissions, WordPress then loads the post revision data instead of the main post data. The site’s theme and styling are applied to this revision content, and it’s rendered in the user’s browser. This process involves the same template hierarchy and rendering engine as the live site, ensuring an accurate representation of how the post will look once published.

Non-Published Content Handling: It’s important to note that this preview mechanism allows users to see changes in real-time for unpublished (draft or pending) posts as well as changes to already published posts. For published posts, WordPress stores the changes as revisions without affecting the live version until those changes are explicitly published.

Security Measures: The nonce and permission checks play a crucial role in ensuring that only authorized users can access the post previews, protecting unpublished content from unauthorized access.

This engineering design enables WordPress users to securely preview their content, ensuring that only the intended changes are published to the live site. It provides a precise preview of how the content will be presented to the end-users.

Let’s dive into how Faust.js with the App Router replicates this experience and engineering in headless WordPress from a decoupled architecture.

Faust.js and App Router Support

The experimental app router example project from Faust.js is a boilerplate starter kit that includes a sample site showcasing the utility of functions such as getClient, getAuthClient, faustRouteHandler, loginAction, and logoutAction. This project can serve as a foundation for your future endeavors and as an informative reference for App Routing in headless WordPress. It is designed for those who are proficient with the command line, have fundamental knowledge of Faust.js and Next.js routing, and have an understanding of the basics of JavaScript, WordPress, and Bash.

Now, let’s focus on how it does Post Previews.

How Post Previews Work in Faust.js with the App Router

Remember, everything in the App Router in Faust.js defaults to being a server component unless otherwise specified with the ‘use client’ directive.  Let’s look at the Faust.js App Router project’s folders and files that make Post Previews work along with the Faust.js plugin necessary for this.

Environment Variables

The first action necessary to make post previews work in App Router is the Faust.js plugin’s secret key, 

To get the secret key, navigate to the ‘Add Plugins’ page in WP Admin and search for the Faust.js plugin.

Once that is installed and activated, when you hover over the settings option in the left-side hamburger menu, it will display a Faust option.  Click on that and you will see this page:

 It is on this page that you can grab your secret key and your front-end URL which in a development server case, it’s going to be off port 3000 on local host.  The last thing you need to get is your WordPress site URL.

Now, navigate over to your code editor. In the .env.local file that you created when spinning up the boilerplate, you can add those values to their keys like so:

Faust.js API Route Handler

Once you have your environment variables set, ensure that you have a directory in the root of the app folder called api.  In this api folder, you should have a nested folder called faust which will contain a file called [route].ts.  It should look like this:

What this code executes is the handling of the endpoints for the auth token and login/logout functionality.  

Authenticated Requests

Navigate to the dynamic route segment that is set by the slug as its parameter which is the [slug]/hasPreviewProps.ts file in the root of the app folder.  You should see this:

export function hasPreviewProps(props: any) {
  return props?.searchParams?.preview === 'true' && !!props?.searchParams?.p;
}

The function hasPreviewProps checks if the preview mode is activated and if there is a post ID present in the properties passed to it. It returns true only if both conditions are met: the preview parameter is set to ‘true’ and a post ID is specified. This is used to determine if a post preview should be displayed. If either condition is not fulfilled, the function returns false, indicating that the normal, non-preview content should be rendered. This helps in conditionally showing either the live post or its preview during development.

Now that we have a function to help check if previews are activated and present, let’s look at the page.tsx file in the same directory to see how authentication and rendering the preview on the content works.

import { getAuthClient, getClient } from '@faustwp/experimental-app-router';
import { gql } from '@apollo/client';
import { hasPreviewProps } from './hasPreviewProps';
import { PleaseLogin } from '@/components/please-login';

export default async function Page(props) {
  const isPreview = hasPreviewProps(props);
  const id = isPreview ? props.searchParams.p : props.params.slug;

  let client = isPreview ? await getAuthClient() : await getClient();

  if (!client) {
    return <PleaseLogin />;
  }

  const { data } = await client.query({
    query: gql`
      query GetContentNode(
        $id: ID!
        $idType: ContentNodeIdTypeEnum!
        $asPreview: Boolean!
      ) {
        contentNode(id: $id, idType: $idType, asPreview: $asPreview) {
          ... on NodeWithTitle {
            title
          }
          ... on NodeWithContentEditor {
            content
          }
          date
        }
      }
    `,
    variables: {
      id,
      idType: isPreview ? 'DATABASE_ID' : 'URI',
      asPreview: isPreview,
    },
  });

  return (
    <main>
      <h2>{data?.contentNode?.title}</h2>
      <div
        dangerouslySetInnerHTML={{ __html: data?.contentNode?.content ?? '' }}
      />
    </main>
  );
}


At the very top of the file, the necessary modules are imported, including functions for authentication and GraphQL queries, the utility function to check for preview props, and a component to prompt for login if needed.

Following our imports, we define an asynchronous Page function component that takes props as an argument.

Within this function, we have a preview check.  We use the hasPreviewProps helper function to determine if the page is in preview mode (isPreview) and sets the id based on whether it’s a preview or a published page, using query parameters (searchParams.p) for previews or URL parameters (params.slug) for published content.

After that, we initialize the GraphQL Client with authentication if it’s a preview with the getAuthClient function, otherwise it initializes a regular client with getClient. If the client can’t be initialized, it returns a <PleaseLogin /> component to prompt the user to log in.

export default async function Page(props) {
  const isPreview = hasPreviewProps(props);
  const id = isPreview ? props.searchParams.p : props.params.slug;

  let client = isPreview ? await getAuthClient() : await getClient();

  if (!client) {
    return <PleaseLogin />;
  }

Once that is done, we execute a WPGraphQL Query using the client.query from Apollo to fetch content by variables which are the id and the idType, and that differs based on whether it’s a preview or not. It asks for the title, content, and date of a content node.

const { data } = await client.query({
    query: gql`
      query GetContentNode(
        $id: ID!
        $idType: ContentNodeIdTypeEnum!
        $asPreview: Boolean!
      ) {
        contentNode(id: $id, idType: $idType, asPreview: $asPreview) {
          ... on NodeWithTitle {
            title
          }
          ... on NodeWithContentEditor {
            content
          }
          date
        }
      }
    `,
    variables: {
      id,
      idType: isPreview ? 'DATABASE_ID' : 'URI',
      asPreview: isPreview,
    },
  });

Finally, the component the main content of the page inside a <main> tag, using the data from the WPGraphQL query to populate the title and the content (using dangerouslySetInnerHTML for the content to render HTML).

return (
    <main>
      <h2>{data?.contentNode?.title}</h2>
      <div
        dangerouslySetInnerHTML={{ __html: data?.contentNode?.content ?? '' }}
      />
    </main>
  );

This setup allows the page to dynamically render the correct version of a post or page based on whether the user is requesting a preview or the live content.

Stoked!!!! Let’s see this work in action!

Conclusion

Faust.js with support for the App Router is a new version of the most used headless WP meta framework on top of Next.js 14. It introduces new ways to handle data, create routes and files as well as rendering methods.  Mix it with headless WordPress and WPGraphQL with Post Previews and you have an easy entry into its core functionality.   We hope you have a better understanding of how it all works together.

As always, stoked to hear your feedback and any questions you might have on headless WordPress! Hit us up in our Discord!

The post Post Previews in the App Router with Faust.js for headless WordPress appeared first on Builders.

]]>
https://wpengine.com/builders/post-previews-in-the-app-router-with-faust-js/feed/ 0
Understanding The Templating System in Faust.js https://wpengine.com/builders/understanding-the-templating-system-in-faust-js/ https://wpengine.com/builders/understanding-the-templating-system-in-faust-js/#respond Fri, 23 Feb 2024 17:24:38 +0000 https://wpengine.com/builders/?p=31504 Templates in Faust bring the power of the WordPress Template Hierarchy to your JavaScript frontend application. This article is a high-level guide to walk you through how templates are resolved […]

The post Understanding The Templating System in Faust.js appeared first on Builders.

]]>
Templates in Faust bring the power of the WordPress Template Hierarchy to your JavaScript frontend application. This article is a high-level guide to walk you through how templates are resolved and how to create your first templates using this system.

Prerequisites

To benefit from this article, you will need to have a basic understanding of Faust.js, headless WordPress, and WPGraphQL.

This article also assumes that you already have a WP install and a Faust.js app created and connected.  If you do not, please refer to the Faust.js documentation.

If you need a more basic tutorial, please reference this article on the subject matter here.

The Traditional WordPress Template Hierarchy

Before we dive into what the templating system is in Faust.js, let’s quickly go over what it mimics in traditional WordPress. 

The WordPress template hierarchy is a system that WordPress uses to decide which template files to use when generating a particular page on a WordPress site. This hierarchy is designed to provide a flexible and efficient method for determining the layout and structure of a page based on the type of content being presented.

When a visitor accesses a page on a WordPress site, WordPress runs a query to determine the type of content requested (e.g., a blog post, a specific page, a category archive, etc.). It then consults the template hierarchy to identify the most appropriate template file to use to display this content. The hierarchy is structured as a series of decisions WordPress makes, looking for template files in a specific order. If it doesn’t find a specific template file, it moves on to a more generic template until it finds a match.

The hierarchy starts with the most specific template files (like those for individual posts or pages) and moves towards more general templates (like archive or index templates) if the more specific templates are not present in the theme. This allows theme developers to create highly customized experiences for different types of content by creating specific template files, while also providing default templates that ensure content is always presented, even if no custom templates are available.

For instance, for a single blog post, WordPress will first look for a template specific to the post’s ID, then for a template for the post’s slug, followed by a template for the post type, and so on, down to more generic templates like single.php and finally index.php if no other template is found.

Here is an image of the template hierarchy:

The Templating System in Faust.js

Now that we understand what Faust.js is mimicking from WordPress in its templating system, let’s discuss how templates are resolved in it. 

The template resolver works by sending a preliminary GraphQL request (called the Seed Query) for the given URI in WordPress. The response includes data like the database ID, slug, content type, etc, which is then used to determine what the possible templates are for the given URI.  This is how traditional WordPress does it but in JavaScript! Stoked!!!

In the next few sections, we will dissect the folder and file structure of the default boilerplate template system.

The WP-Templates Directory

The Faust.js template system obeys the Next.js Pages Router method.  When you spin up the boilerplate npm package, you will see a directory in the root of the project called wp-templates.  You can name this anything you want, but out of the box, this name makes the most sense.   This is the folder that will house your Faust.js templates.

The Default Files

The files that come out of the box with the Faust.js npm package and the pages that they resolve and render are as follows:

category.js :  This resolves and renders the category archive page with the posts that are related within certain categories from the WordPress backend

front-page.js : This resolves and renders the front page of the Faust.js boilerplate that contains your general settings data as well as anything you want to add to the front-page template.  When first spun up, it just renders HTML that says this is a front page.

index.js: This is where your template files will be kept and sifted through for the system to go through what template is best to resolve and render.

page.js : This file resolves and renders any page post type in WordPress.

single.js:  This file will render any post from the post type menu. Any individual blog posts will resolve and render this template. 

tag.js : This file is the archive page for a specific page. For example, if you have a tag called “apple” it will resolve all of the posts tagged as “apple”.

Here is an image of the boilerplate folder with files:

Create Your First Custom Template

Now that we have an understanding of how the templating works in Faust.js, let’s create a custom template.

The first template we will make is a custom sample page template.  Navigate to the wp-templates directory at the root of your Faust.js project and create a file called sample-page.js.  Once the file is created, copy and paste this code onto the file:

import { gql } from "@apollo/client";

// The Component is required
export default function Component(props) {
  return (
    <>
      <h1>{props.data.page.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: props.data.page.content }} />
    </>
  );
}

Component.query = gql`
  query GetPageDataByURI($uri: ID!) {
    page(id: $uri, idType: URI) {
      title
      content
      slug
    }
  }
`;

Component.variables = (seedQuery, context) => {
  return {
    uri: seedQuery?.uri,
  };
};


Component.variables = (seedQuery, context) => {
  return {
    uri: seedQuery?.uri,
  };
};

Let’s break down what is happening in the code block.

At the top of the file, we import the gql tag from the Apollo Client to parse WPGraphQL queries.

Next, we define a functional component named Component that takes props as an argument.  This will be the default exported component.

Following that we return some JSX to render the HTML using the React escape hatch to render the content from a string.  We traverse that data path accurately to gain access to the content of the page from WordPress, in this case, just the page content and the page title.

Below that, we have our WPGraphQL queries the Component.query syntax from Faust to assign the query prop of the component.  We are querying for page data by a variable which is its URI.

Lastly, we need to add its variable component function.  We define that and assign it a variables property which is used to compute the variables of the WPGraphQL query based on the input parameters seedQuery and context.  

Then we return an object containing the variables for the query and access the URI by chaining the seedQuery.  

The Index File

Before we test this out and see if this renders correctly on the browser, the finishing step is to add and specify the template in our index.js file in the wp-templates directory.  

The index.js file is the most important file in the wp-templates directory when using Faust.js for headless WordPress. It acts as the control center, telling the system which template to use for showing content on the browser. Without setting up this file, the website won’t display pages correctly, if at all.

I like to think of it as a directory or map. It lists all the templates you have and matches them with what the user wants to see. This setup is vital for making sure the right template is picked for each page request. Without this file, the system is like a library without an index; you wouldn’t know where to find anything.

In the wp-templates folder, import your sample-page.js file at the top, then in the export object add the key identifier and value of the imported module like so:

Notice that we make the key ID string unique by calling it page-sample-page. If we do not, the page will conflict with the page.js file and render that instead. Make sure to make the key ID string unique in relation to the other files in your wp-templates folder.

 We can now test this out and see if it works.

Go to your WP Admin and navigate to the Pages option on the left-hand side of the hamburger menu:

Make a test sample page.  You can call this whatever you want.  I called it Test Faust.js Sample Page.  Click on the page link you just created to edit it:

In the URL field, make sure the permalink reflects the name of your file on the frontend.  In this case, it is sample-page.  This will tell Faust.js what template to resolve.

Finally, click the link to view the page and you should see this on the browser:

Conclusion

The template hierarchy in traditional WordPress is an important system to help the overall UI experience for users on a website.  In headless WordPress, Faust.js compliments that hierarchy to mimic it on the JavaScript frontend. I hope this gave you a better understanding of how the basics work on the Faust.js side.

Stay tuned for my next article on this matter where we will dive a little deeper and create custom templates in Faust.js with WPGraphQL for ACF.  

As always, stoked to hear your feedback and any questions you might have on headless WordPress! Hit us up in our Discord!

The post Understanding The Templating System in Faust.js appeared first on Builders.

]]>
https://wpengine.com/builders/understanding-the-templating-system-in-faust-js/feed/ 0
How to Set Up WordPress As A Headless CMS https://wpengine.com/builders/set-up-wordpress-as-a-headless-cms/ https://wpengine.com/builders/set-up-wordpress-as-a-headless-cms/#respond Thu, 15 Feb 2024 19:19:35 +0000 https://wpengine.com/builders/?p=31487 Headless WordPress is a website or omnichannel app that uses WordPress content, delivered by the REST API or GraphQL to frontends developed outside WordPress (e.g., Next.js, Nuxt.js, React, Vue). Before […]

The post How to Set Up WordPress As A Headless CMS appeared first on Builders.

]]>
Headless WordPress is a website or omnichannel app that uses WordPress content, delivered by the REST API or GraphQL to frontends developed outside WordPress (e.g., Next.js, Nuxt.js, React, Vue). Before you start building a frontend site that connects to your WordPress backend for content, you need to configure your WordPress site with some recommended plugins.

Installing Plugins

WPGraphQL

WPGraphQL is a plugin for WordPress that extends the WordPress API to support GraphQL requests. This plugin is highly recommended, as it makes it much easier to work with WordPress content. In most cases, you can use the default configuration for WPGraphQL, so installing the plugin is enough to get you started.

Advanced Custom Fields

Advanced Custom Fields (ACF) lets you take full control of your WordPress edit screens and custom field data. It supports a ton of different field types that you can attach to content types in WordPress. Assuming you are using WPGraphQL, you should also install the companion WPGraphQL For Advanced Custom Fields plugin. This companion plugin will let you extend the WPGraphQL API with ACF information. There is no configuration necessary before you can start working with ACF.

Faust.js

Faust.js provides a set of tools to make building frontend applications with WordPress as the headless CMS a pleasant experience for developers and publishers. The plugin helps with post previewing, authentication, fetching data, and more. It is used in conjunction with the Faust.js framework to build out the frontend of your headless site.

The Faust.js plugin requires some customization when you first install it. You can find the settings for the plugin in Settings → Faust. You will want to configure your Frontend site URL to be your frontend website’s root URL. For example, if you are running a Node site on your local machine on port 3000, your Front-end site URL should be “http://localhost:3000”. You will need to connect it with the frontend Faust.js app in a .env.local file.

After you install the plugins listed above, your WordPress site will be ready for headless development. While there are certainly more plugins you can use; these are the base plugins we recommend based on what we commonly use to build headless WordPress sites!

The post How to Set Up WordPress As A Headless CMS appeared first on Builders.

]]>
https://wpengine.com/builders/set-up-wordpress-as-a-headless-cms/feed/ 0