Imagine you are building a very smart, digital house.
- WordPress is the furniture store where you write and store all your words and images.
- Next.js is the actual house where visitors come to see your furniture.
- Vercel is the land where your house is built so the whole world can visit it.
Here is exactly how to build this house, step by step.
Phase 1: The Blueprint (Folders You Need to Create)
Before we write any code, we need to create empty folders (like drawing rooms on a blueprint) so our files have a place to live.
In your VS Code, look at your main project folder. Create these exact folders inside it:
- src (This is the main box for your house).
- Inside src, create three smaller folders:
- app (For the rooms people will visit, like the Homepage).
- components (For the building blocks, like the Translator).
- lib (For your tools, like the Telephone Line).
Phase 2: Filling the Rooms (The Files and Code)
Now we will create 5 specific files inside those folders and give them their instructions.
1. The Secret Safe (.env.local)
- Where to put it: Outside all folders (right at the bottom of your VS Code list).
- What it is: A hidden vault that holds the map to your WordPress furniture store.
- Why we need it: We do not want bad guys on the internet to know where our WordPress site lives. This file hides that address.
- How it works: You put the URL here, and the house asks the Safe for the address whenever it needs it.
Add this code:
Plaintext
NEXT_PUBLIC_WORDPRESS_API_URL=https://wp.yourwebsite.com/graphql
2. The Telephone Line (src/lib/wordpress.ts)
- Where to put it: Inside the src/lib folder.
- What it is: The actual phone that calls WordPress.
- Why we need it: Instead of building a new phone for every single room in the house, we build one really good phone here and let every room share it.
- How it works: It looks at the Safe to get the phone number (the URL), makes the call to WordPress, gets your words and pictures, and brings them back.
Add this code:
TypeScript
export async function fetchGraphQL(query: string, variables = {}) {
const wpUrl = process.env.NEXT_PUBLIC_WORDPRESS_API_URL;
if (!wpUrl) {
throw new Error(“Missing WordPress API URL in .env.local”);
}
const res = await fetch(wpUrl, {
method: “POST”,
headers: { “Content-Type”: “application/json” },
body: JSON.stringify({ query, variables }),
next: { revalidate: 60 }, // This tells the house to check for new furniture every 60 seconds
});
const json = await res.json();
return json.data;
}
3. The Translator (src/components/BlockRenderer.tsx)
- Where to put it: Inside the src/components folder.
- What it is: A robot that translates languages.
- Why we need it: WordPress speaks a language called “Blocks.” Our new house speaks a language called “React.”
- How it works: The Telephone Line brings back WordPress Blocks. The Translator catches them and magically turns them into React code so they look beautiful on your screen.
Add this code:
TypeScript
import React from ‘react’;
interface BlockRendererProps {
htmlContent: string;
}
export function BlockRenderer({ htmlContent }: BlockRendererProps) {
return (
<div
className=”prose prose-invert max-w-none”
dangerouslySetInnerHTML={{ __html: htmlContent }}
/>
);
}
4. The Front Door (src/app/page.tsx)
- Where to put it: Inside the src/app folder.
- What it is: Your main Homepage.
- Why we need it: When someone types in your main website name, this is the very first thing they see.
- How it works: This file grabs the Telephone Line, dials WordPress, and says: “Please give me the furniture for Page ID 8.” Then, it hands that furniture to the Translator to display it.
Add this code:
TypeScript
import { notFound } from “next/navigation”;
import { fetchGraphQL } from “@/lib/wordpress”;
import { BlockRenderer } from “@/components/BlockRenderer”;
import { Metadata } from “next”;
const HOME_QUERY = `
query HomePageExact {
page(id: “8”, idType: DATABASE_ID) {
title
content
seo {
title
metaDesc
}
}
}
`;
export async function generateMetadata(): Promise<Metadata> {
const data = await fetchGraphQL(HOME_QUERY);
if (!data?.page?.seo) return { title: “Home” };
return {
title: data.page.seo.title,
description: data.page.seo.metaDesc,
};
}
export default async function Home() {
const data = await fetchGraphQL(HOME_QUERY);
if (!data || !data.page) return notFound();
return (
<main className=”w-full min-h-screen bg-[#0E1623]”>
<BlockRenderer htmlContent={data.page.content} />
</main>
);
}
5. The Magic Hallway (src/app/[…slug]/page.tsx)
- Where to put it: Inside src/app, create a new folder named exactly […slug] (include the brackets and dots). Inside that folder, create page.tsx.
- What it is: A hallway with endless doors.
- Why we need it: If you have 100 blog posts, you do not want to build 100 separate files. This one file acts as a trap.
- How it works: If a user types /about-us, this file catches the word “about-us”, asks the Telephone Line for that specific page, and builds the room instantly.
Add this code:
TypeScript
import { notFound } from “next/navigation”;
import { fetchGraphQL } from “@/lib/wordpress”;
import { BlockRenderer } from “@/components/BlockRenderer”;
const PAGE_QUERY = `
query GetPageByUri($uri: String!) {
nodeByUri(uri: $uri) {
… on Page { title, content }
… on Post { title, content }
}
}
`;
export default async function CatchAllPage({ params }: { params: { slug: string[] } }) {
const uri = `/${params.slug.join(“/”)}/`;
const data = await fetchGraphQL(PAGE_QUERY, { uri });
if (!data || !data.nodeByUri) return notFound();
return (
<main className=”w-full min-h-screen bg-[#0E1623] p-10″>
<h1 className=”text-4xl font-bold mb-8″>{data.nodeByUri.title}</h1>
<BlockRenderer htmlContent={data.nodeByUri.content} />
</main>
);
}
Phase 3: Saving to the Cloud (GitHub Sync)
Right now, your house only exists on your computer. If your computer breaks, the house is gone. We need to save a copy to GitHub (a giant, safe digital library in the sky).
You can do this two ways: the easy click way, or the cool hacker way.
Option A: The Easy Click Way (Source Control)
- Look at the left side of VS Code. Click the icon that looks like a little tree branch with circles (this is Source Control).
- In the text box, type a message like: “Built my house files.”
- Click the blue button that says Commit. (This takes a picture of your house).
- Click the button that says Sync Changes. (This sends the picture up to the GitHub library).
Option B: The Hacker Way (Terminal Bash)
Instead of clicking, you can tell your computer exactly what to do using text commands. Open your Terminal in VS Code and type these three commands, pressing “Enter” after each one:
- git add . (Translation: “Please gather all the new files I just made.”)
- git commit -m “Built my house files” (Translation: “Put them in a box and put this sticky note on the box.”)
- git push (Translation: “Throw the box up into the GitHub cloud.”)
Phase 4: Going Live to the World (Vercel)
Your house code is safe in the GitHub library. Now, we use Vercel. Vercel is like the construction worker who takes your code from the library and actually builds the house on the internet so your friends can visit it.
- Go to Vercel.com and log in with your GitHub account.
- Click Add New… and choose Project.
- You will see your house from GitHub. Click Import.
STOP! THE MOST IMPORTANT STEP:
Remember the Secret Safe (.env.local)? When you sent your code to GitHub, the Safe stayed behind on your computer to keep it secret. Because Vercel is downloading the code from GitHub, Vercel doesn’t have the Safe! We must give it the key.
- On Vercel, scroll down to Environment Variables.
- In the Name box, type: NEXT_PUBLIC_WORDPRESS_API_URL
- In the Value box, type your WordPress URL: https://wp.yourwebsite.com/graphql
- Click Add.
Now, click the big DEPLOY button!
Vercel will take your code, read the URL you just gave it, use the Telephone Line to call WordPress, grab your furniture, run it through the Translator, and put it on your Homepage.
In about 60 seconds, your site is live on the internet!
This code is the exact missing link! This is the “Translator” we talked about earlier, but seeing your actual code makes it so much easier to explain. You are using a brilliant method called HTML Parsing with Class Mapping.
To a beginner, this code looks like a giant, intimidating list. But the concept behind it is actually incredibly simple.
Here is exactly how to explain this “Block matching” system in your guide, using a simple “Sticky Note” analogy so anyone can understand how to make a block appear exactly where they want it.
How to Put Custom Blocks on Your Page (The Sticky Note System)
Overview: Next.js and WordPress do not naturally speak the same language. If you build a beautiful, interactive <HeroHome /> block in Next.js, WordPress has no idea what that is.
So, how do we tell WordPress where to put it? We use Sticky Notes (also known as CSS Classes).
Here is the 3-step process of how we build a block and place it exactly where we want it on the page.
Step 1: Build the React Component (Next.js)
First, we build the actual design in Next.js. Let’s say we build a cool banner and call it <WpHeroVisual />.
- This block lives in our Next.js code folder.
- Right now, it is just waiting in the wings. It needs to be called to the stage.
Step 2: Place the Sticky Note (WordPress)
Now, we go into our WordPress dashboard to write our page.
We want our cool Hero banner at the very top of the page. Here is what we do:
- Open your page in the WordPress Editor.
- Add a simple Group Block at the top of the page.
- Look at the right-side menu, scroll down to Advanced, and find the box called Additional CSS class(es).
- Type in our secret sticky note word:
section-Wphero-visual - Save the page.
What just happened? You didn’t actually build the banner in WordPress. You just placed an empty, invisible box at the top of the page with a sticky note on it that says section-Wphero-visual.
Step 3: The Matchmaker (The BlockRenderer)
When a user visits your website, Vercel downloads that WordPress page. It sees all your normal text, but then it hits that empty box with the sticky note.
This is where our BlockRenderer file steps in. The BlockRenderer is a Matchmaker. It reads the whole page top-to-bottom and looks for sticky notes.
Look at this exact line from our code:
JavaScript
if (classes.includes("section-Wphero-visual")) return<WpHeroVisual />;
Translation: “If you find a sticky note that says section-Wphero-visual, delete the empty box and drop the real <WpHeroVisual /> Next.js component into that exact spot!”
How do I control the order?
It is completely controlled by WordPress!
Because the BlockRenderer reads the HTML from top to bottom, the order of your blocks in WordPress is exactly how they will appear on the live site.
- Want the
FAQSectionat the bottom? Put a WordPress block at the bottom with the classsection-FAQ. - Want the
WPDevCarouselin the middle? Put a block in the middle with the classsection-wpdev-carousel.
You are simply building a skeleton in WordPress, and Next.js is adding the muscle and skin on top of it.
Leave a Reply