How to use Next.JS with Shopware API Hello Guys, Today in this blog we will see all about the API integration of the Shopware product detail page with the Next JS.
Shopware 6 is an open-source, content management system (CMS) that helps online merchants manage their inventory and orders. It’s based on Symfony Framework and Vue and is supported by a worldwide community.
First, we’ll have some discussion about NextJS and begin by introducing the concept of Shopware and its API.
What is NextJS?
Next Js is a full-stack web development react framework. Which is a free and open-source front-end react library framework for building user interfaces based on UI components.
All the features needed to create a variety of websites and apps are provided by NextJs, including routing, static and server rendering, static-side regeneration, and support for Typescript.
For CSS design if you want to make a good user interface you can choose your desired Dependencies for the design part.
About Shopware API
The Shopware API allows developers to interact with and integrate Shopware with other systems and applications. It provides a set of services that enable developers to perform various operations, such as managing products, customers, orders, and shopping carts.
Starting Out
Setting up the project – The first step is to set up this project. Check out this Setup NextJS Project blog that explains everything about setting up a NextJS project. Also, we are using Tailwind CSS within the Project.
Global Variable Setup – We’re going to create a file named .env in the root directory and add the following code.
//------------.env--------------// SHOPWARE_ENDPOINT=<SHOPWARE_ENDPOINT> APP_URL=https://myshopware.com/ SW_ACCESS_KEY=<SW_ACCESS_KEY> IMAGE_DOMAIN=<myshopware.com>
You also need to define environment variables in your next.config.js file. If you don’t define them, you won’t be able to use these variables in the front end.
/** @type {import('next').NextConfig} */ const nextConfig = { env: { SW_ACCESS_KEY: process.env.SW_ACCESS_KEY, SHOPWARE_ENDPOINT: process.env.SHOPWARE_ENDPOINT, IMAGE_DOMAIN: process.env.IMAGE_DOMAIN, }, images: { domains: [process.env.IMAGE_DOMAIN], }, reactStrictMode: true, } module.exports = nextConfig
Make sure you have the required API endpoint URLs (product, authenticate, and other parameters). To fetch data from the Shopware API, you need to use the Fetch function or a library such as Axios.
API Response (The mentioned image demonstrates Shopware’s product detail page’s API response):
Create a Route file to Display the Product Detail Page:
The following code will be added to a file called [urlKey].js that will be created in pages/product/[urlKey].js.
//---------------pages/product/[urlkey].js-----------// import Image from "next/image"; import React from "react"; const Product = ({ product }) => { const { cover, calculatedPrice, translated, availableStock } = product; return ( <React.Fragment> <div className="mt-6"> <div className="lg:px-24 md:px-12 px-3"> <div className="container mx-auto px-4"> <div className="lg:col-gap-12 xl:col-gap-16 mt-3 grid grid-cols-1 gap-12 lg:mt-12 lg:grid-cols-5 lg:gap-16"> <div className="lg:col-span-3 lg:row-end-1"> <div className="lg:order-2 "> <div className="max-w-xl overflow-hidden rounded-lg"> <Image className="h-[70vh] mix-blend-darken" src={cover?.media?.url} width={500} height={230} priority={true} alt="loading" /> </div> </div> </div> <div className="lg:col-span-4 lg:row-span-2 lg:row-end-2"> <h1 className="sm: text-2xl font-bold text-gray-900 sm:text-3xl"> {translated.name} </h1> <div className=" mt-3"> <p className=" text-sm font-medium text-gray-500"> In Stock : {availableStock} </p> </div> <h2 className="mt-3 text-base text-gray-900">Description: </h2> <div className="mt-3 flex select-none flex-wrap items-center gap-1"> <section> <div dangerouslySetInnerHTML={{ __html: translated.description.toString(), }} ></div> </section> </div> <div className="mt-10 flex flex-col items-center justify-between space-y-4 border-t border-b py-4 sm:flex-row sm:space-y-0"> <div className="flex items-end"> <h1 className="text-3xl font-bold"> ${calculatedPrice.totalPrice} </h1> </div> <button type="button" className="inline-flex items-center justify-center rounded-md border-2 border-transparent bg-gray-900 bg-none px-12 py-3 text-center text-base font-bold text-white transition-all duration-200 ease-in-out focus:shadow hover:bg-gray-800" > <svg xmlns="http://www.w3.org/2000/svg" className="shrink-0 mr-3 h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2} > <path strokeLinecap="round" strokeLinejoin="round" d="M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z" /> </svg> Add to cart </button> </div> </div> </div> </div> </div> </div> </React.Fragment> ); }; export default Product; export async function getStaticPaths() { let paths = []; try { const data = await fetchProduct(); const products = data?.products?.items || []; paths = products.map((product) => ({ params: { urlKey: product?.url_key || "404" }, })); } catch (error) { console.error("Error fetching data from API:", error); } return { paths, fallback: "blocking" }; } export async function getStaticProps({ params }) { const productInfo = await fetchProduct(params?.urlKey); if (productInfo.length > 0) { return { notFound: true, }; } return { props: { product: productInfo?.product, }, revalidate: 100, }; } const fetchProduct = async (urlKey = null) => { if (urlKey) { const URL = `${process.env.SHOPWARE_ENDPOINT}/product/${urlKey}`; const response = await fetch(URL, { method: "POST", headers: { "Content-Type": "application/json", Accept: "application/json", "sw-access-key": process.env.SW_ACCESS_KEY, }, body: undefined, }); if (response.status !== 200) { throw new Error(`API request failed with status ${response.status}`); } return response.json(); } };
You can see the result on http://localhost:3000
Start Shopware Headless Development with Webkul.
Happy Coding 🙂
Be the first to comment.