Whats up Guys, On this weblog we are going to begin a journey to construct NextJs Theme in Magento 2.
Once we mix Magento 2 with Nextjs then makes you probably the most highly effective e-commerce platforms so we are going to information you thru this weblog step-by-step to the NextJS theme throughout the Magento 2 GraphQL API.
Magento 2 Graphql API Overview
Magento 2 is a well-liked open-source e-commerce platform, that launched GraphQl API assist for client-side expertise like ReactJs and NextJs. So We are going to work on the GraphQl API endpoints for the NextJS theme.
Principally, GraphQL is a question language for APIs that gives the facility to ask for precisely what they want and nothing extra.
Magento gives the GraphQl endpoints by coming into http://<magento2-server>/graphql within the URL bar of your ChromeiQl extension.
You possibly can see the API Response of product endpoints.

Creating the ReactJs venture utilizing Magneto 2.
Step 1: Mission Setup – On this first step, we have to arrange the NextJs venture. You possibly can comply with this setup nextjs venture weblog.
For CSS UI, you should use the Tailwind CSS dependencies for Expertise throughout the NextJs Mission.
Within your terminal run this command to put in Tailwind CSS.
npm set up -D tailwindcss
Step 2: Arrange the Apollo client- We are going to want Apollo consumer dependencies that aid you with each Apollo Shopper and GraphQl API.
Run the next command to put in each of those packages:
npm set up @apollo/consumer graphql
Principally, Apollo Shopper is a state administration library to be used to fetch, cache, and modify utility knowledge.
Lastly, arrange your Nextjs Mission, and Your venture listing construction should be like this.
. ├── pages/ │ ├── api │ ├── hiya.js │ ├── app.js │ ├── _document.js │ └── index.js ├── public/ │ ├── favicon.ico │ ├── subsequent.svg │ └── vercel.svg ├── kinds/ │ └── world.css ├── subsequent.config.js ├── package-lock.json ├── package deal.json ├── postcss.config.js ├── README.md ├── tailwind.config.js └── tsconfig.js
Step 3: World Variable Setup – We’re going to create a file named .env within the root listing and add the next code.
MAGENTO_ENDPOINT=http://<magento2-server>/graphql
Step 4: Export World Variable – We have to outline the worldwide variable within the subsequent.config.js file. in any other case, you can’t use this variable on the entrance finish. So write the next code.
//------------next.config.js-----------// /** @sort {import('subsequent').NextConfig} */ const nextConfig = { env: { MAGENTO_ENDPOINT: course of.env.MAGENTO_ENDPOINT, }, reactStrictMode: true, }; module.exports = nextConfig;
Step 5: Create the GraphQl File – We’re going to create the GraphQl Question file title product.graphql in elements/graphql/product.graphql and the folloeing code. this file will assist to fetch knowledge API response.
//-------------components/graphql/product.graphql-------------// question ProductQuery($filters: ProductAttributeFilterInput) { merchandise(filter: $filters) { objects { id title sku description{ html } short_description{ html } picture { disabled label place url } rating_summary media_gallery{ url place label disabled } } } }
Step 6: Create a Route file to Show the Product – We’re going to create a file named [urlKey].js in pages/product/[urlKey].js.
On this weblog, We’re utilizing this SSG function. SSG means Static Web site Era (SSG) is a strong function in NextJs. that generates the HTML web page at a construct time net utility This HTML web page will then be reused on every request.
GetStaticPaths is an async operate which is used to get the paths we need to pre-render primarily based on merchandise
import PRODUCT_QUERY from '../../elements/graphql/Product.graphql'; export async operate getStaticPaths() { let paths = []; const { knowledge } = await consumer.question({ question: PRODUCT_QUERY, variables: { filters: {}, pageSize: 12 }, }); const merchandise = knowledge?.merchandise?.objects || []; paths = merchandise.map((product) => ({ params: , })); return { paths, fallback: 'blocking' }; }
GetStaticProp can be an async operate that generates knowledge on the construct time of generated path by the getStaticPaths operate.
export async operate getStaticProps({ params }) { const { knowledge } = await consumer.question({ question: PRODUCT_QUERY, variables: { filters: { url_key: { eq: params?.urlKey } } }, }); const product = knowledge?.merchandise?.objects?.[0] || null; if (!isValidObject(product) || !product.sku) { return { notFound: true, }; } return { props: { product: product, }, revalidate: 100, }; }
GraphQl API response

Closing Code and UI Design In keeping with the API Response.
//---------------pages/product/[urlkey].js-----------// import Picture from 'subsequent/picture'; import { useState } from 'react'; import PRODUCT_QUERY from '../../elements/graphql/Product.graphql'; const Product = ({ product }) => { const { thumbnail, price_range, sku } = product; const [addtocart, setAddtocart] = useState(1); const add = () => { setAddtocart(addtocart + 1); }; const sub = () => { addtocart > 1 && setAddtocart(addtocart - 1); }; return ( <div class="grid grid-cols-5 gap-4 w-[85%] mx-auto my-5"> <div className="col-span-2 border border-1 border-solid border-slate-400 rounded"> <Picture src={thumbnail?.id} width={500} peak={500} /> </div> <div className="col-span-3 mx-10"> <div className=""> <div show="grid"> <p className="font-[500] text-[2.5rem]"></p> <div className="flex justify-between "> <p className="text-price" sx={{ paddingTop: 1.5 }}> <span className="font-semibold"> $ {price_range?.minimum_price?.regular_price?.worth} </span> <s className="pl-4 italic font-light text-fadedText"> {price_range?.low cost?.amount_off} </s> </p> <p variant="body1" className="mt-7"> Sku : {sku} </p> </div> <div className="flex"> <button onClick={sub} aria-label="increment" className="text-white w-10 rounded-l h-8 border-0 cursor-pointer bg-secondary hover:bg-brand hover:contrast-75" > - </button> <enter max={6} sort="textual content" className="relative w-14 border-[1px] border-gray flex items-center px-3 font-semibold text-center text-gray-700 outline-none cursor-default -z-10 readonly focus:outline-none text-md hover:text-black focus:text-black md:text-base" min={1} worth={addtocart} id="amount" placeholder="0" /> <button aria-label="increment" className="text-white w-10 h-8 rounded-r border-0 cursor-pointer bg-secondary hover:bg-brand hover:contrast-75" onClick={add} > + </button> </div> <p className="pt-3 text-hoverEffect text-[16px] "> </p> </div> <button colour="secondary" variant="contained" className="w-full py-4 mx-auto" sort="submit" > Add to cart </button> </div> </div> </div> ); }; export default Product; export async operate getStaticPaths() { let paths = []; const { knowledge } = await consumer.question({ question: PRODUCT_QUERY, variables: { filters: {}, pageSize: 12 }, }); const merchandise = knowledge?.merchandise?.objects || []; paths = merchandise.map((product) => ({ params: , })); return { paths, fallback: 'blocking' }; } export async operate getStaticProps({ params }) { const { knowledge } = await consumer.question({ question: PRODUCT_QUERY, variables: { filters: { url_key: { eq: params?.urlKey } } }, }); const product = knowledge?.merchandise?.objects?.[0] || null; if (!isValidObject(product) || !product.sku) { return { notFound: true, }; } return { props: { product: product, }, revalidate: 100, }; }
You possibly can see the consequence on http://localhost:3000

Begin your Magento 2 Headless Improvement (Adobe improvement) with Webkul.
Pleased Coding!!