Cookies setting

Cookies help us enhance your experience on our site by storing information about your preferences and interactions. You can customize your cookie settings by choosing which cookies to allow. Please note that disabling certain cookies might impact the functionality and features of our services, such as personalized content and suggestions. Cookie Policy

Cookie Policy
Essential cookies

These cookies are strictly necessary for the site to work and may not be disabled.

Information
Always enabled
Advertising cookies

Advertising cookies deliver ads relevant to your interests, limit ad frequency, and measure ad effectiveness.

Information
Analytics cookies

Analytics cookies collect information and report website usage statistics without personally identifying individual visitors to Google.

Information
mageplaza.com

Ultimate Instruction to Build a NextJs Theme in Magento 2

Vinh Jacker | 11-11-2024

Ultimate Instruction to Build a NextJs Theme in Magento 2

Having a modern, fast, and user-friendly interface will set you apart, helping you attract and retain customers successfully.

NextJS, with its powerful optimization capabilities, when combined with the Magento (Adobe Commerce) platform, offers a perfect solution for businesses aiming to enhance user experience and optimize website performance.

This article will guide you step-by-step on building a NextJs theme in Magento 2, helping you create an outstanding and efficient online store.

Introduction about NextJs

NextJs is a framework built on top of React, known for its SEO optimization capabilities, fast page loading performance, and smooth user experience. NextJs enables developers to easily build static and dynamic web applications thanks to features like SSR (Server-Side Rendering) and SSG (Static Site Generation).

Introduction about NextJs

Source

Therefore, NextJs not only helps you create fast and efficient websites but also provides powerful tools and features to manage and optimize your website.

When combined with Magento 2, you’ll have a robust e-commerce platform that is easy to manage and optimize, delivering the best experience for users.

Overview of Magento 2 GraphQL API

Magento 2 provides a powerful GraphQL API that enables developers to easily query and manipulate data from the Magento system. GraphQL allows you to request precisely the data you need, optimizing performance and reducing bandwidth usage compared to traditional APIs like REST.

Magento 2 GraphQL API

Source

When building interfaces with NextJs, using Magento 2’s GraphQL API helps seamlessly connect the frontend and backend, providing the necessary data for pages and interface components.

Therefore, with GraphQL, developers can build applications more quickly, flexibly, and efficiently, significantly improving the user experience.

How to Build a NextJs Theme in Magento 2

To create a NextJS project within Magento 2, let’s delve into the detailed 6 steps below!

Step 1: Setup NextJs

First, you need to install NextJs and set up a new project. Open the terminal and run the following commands:

npx create-next-app my-magento-theme 
cd my-magento-theme 
npm run dev

Step 2: Setup Axios

Axios is a Promise-based HTTP client library for both Node.js and browsers. It offers codebase consistency, meaning the same codebase can run seamlessly in both environments.

Essentially, Axios is a powerful library that helps you easily connect to and query data from Magento 2’s GraphQL API. It’s used to fetch, cache, store, and modify application data.

Step 3: Add css to globals.css

@tailwind base;
@tailwind components;
@tailwind utilities;

Add css to globals.css in Magento NextJs

Step 4: Create GraphQL file

You need to create an additional file productQuery.jsx to create a graphql query. Therefore, the following code will help you:

export const productQuery = `query ProductQuery($filters: ProductAttributeFilterInput) {
 products(filter: $filters) {
   items {
     id
     name
     sku
     description{
       html
     }
     short_description{
       html
     }
     image {
       disabled
       label
       position
       url
     }
     rating_summary
     media_gallery{
       url
       position
       label
       disabled
     }
   }
 }
}`

GraphQL file in Magento NextJs

Step 5: Create API file to get data

Create a file helpers/api.jsx to get data from your Magento site.

import axios from 'axios';


export async function handleRequest({
                                       url = null,
                                       query = '',
                                       method = 'POST',
                                       params = {},
                                       options = {},
                                       variables = {},
                                       clientConfig = {
                                           baseURL: 'Your Magento base url',
                                           timeout: 60000
                                       }
                                   }) {
   const client = axios.create(clientConfig);
try {
   return client
       .request({
           ...options,
           headers: {
               accept: 'application/json',
               ...(options.headers || {})
           },
           url,
           method,
           data: {query, variables},
           params
       })
       .then(({data: {data = {}, errors = []} = {}}) => ({data: data, errors}));
} catch (e) {
   console.log('api error', e);
}


}

Get data from API file in Magento NextJs

Step 6: To display the Product

Create a file named product.js in app

In this case, we’ll utilize the Static Site Generation (SSG) feature in Next.js, which is a powerful feature. It means that the HTML page will be generated at build time and reused on each request.

To pre-generate the paths based on the products, we use the asynchronous function Product.

Final Code and UI Design According to the API Response.

'use client'


import {useState} from "react";
import Image from "next/image";


export 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">
               <Image src={thumbnail?.id} width={500} height={500}/>
           </div>
           <div className="col-span-3 mx-10">
               <div className="">
                   <div display="grid">
                       <p className="font-[500] text-[2.5rem]">{product.name || ''}</p>
                       <div className="flex justify-between ">
                           <p className="text-price" sx=>
               <span className="font-semibold">
                 $ {price_range?.minimum_price?.regular_price?.value}
               </span>
                               <s className="pl-4 italic font-light text-fadedText">
                                   {price_range?.discount?.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>
                           <input
                               max={6}
                               type="text"
                               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}
                               value={addtocart}
                               id="quantity"
                               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] ">
                           {product.short_description?.html ||
                               ''}
                       </p>
                   </div>
                   <button
                       color="secondary"
                       variant="contained"
                       className="w-full py-4 mx-auto"
                       type="submit"
                   >
                       Add to cart
                   </button>
               </div>
           </div>
       </div>
   );
};

Display the product in Magento NextJs

Afterwards, call the Product in the page.tsx file to fetch data onto the page.

import styles from "./page.module.css";
import {Product} from "@/app/product";
import {handleRequest} from "@/helpers/api";
import {productQuery} from "@/app/productQuery";


async function Home() {
   const {data: {products: {items}}} = await getProducts({urlKey: 'fusion-backpack'});
 return (
   <main className={styles.main}>
     <Product product={items[0]} />
   </main>
 );
}


export default Home


export async function getProducts({urlKey = ''}) {
   const data = await handleRequest({query: productQuery, variables: {filters: {url_key: {eq: urlKey}}},})


   return data;
}

Display the product in Magento NextJs

You can see the result on http://localhost:3000

Conclusion

Building a Next.js interface within Magento 2 (Adobe Commerce) brings numerous benefits in terms of performance, user experience, and SEO optimization. By utilizing Next.js alongside Magento 2’s GraphQL API, you can create modern, fast, and efficient e-commerce websites.

Hopefully, this guide has helped you understand the process of building and applying it to your project.

If you encounter any difficulties while building a NextJs theme in Magento 2, don’t hesitate to contact our experts for the best support.

Wishing you success!

Table of content
    Jacker

    With over a decade of experience crafting innovative tech solutions for ecommerce businesses built on Magento, Jacker is the mastermind behind our secure and well-functioned extensions. With his expertise in building user-friendly interfaces and robust back-end systems, Mageplaza was able to deliver exceptional Magento solutions and services for over 122K+ customers around the world.



    Related Post

    Website Support
    & Maintenance Services

    Make sure your store is not only in good shape but also thriving with a professional team yet at an affordable price.

    Get Started
    mageplaza services