Back to Top

How to create Product page using Prestashop API in NextJs

Updated 3 November 2023

How to use Next.JS with Prestashop  Hello Guys, Today in this blog we will see all about the API integration of the Prestashop product detail page with the Next JS.

Let’s get started, as we think you will find this blog to be interactive.

PrestaShop is an entirely free and open-source platform that permits users to develop a fully customizable website in minutes. It makes the eCommerce website development accessible and more manageable.

First, we’ll have some discussion about NextJS and begin by introducing the concept of Prestashop 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.

Searching for an experienced
Prestashop Company ?
Find out More

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 Prestashop API

Basically, the Prestashop API is normally the Rest API which provides the e-commerce product services and serves as the bridge between your application and the Prestashop Platform.

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--------------//
PRESTASHOP_ENDPOINT=<PRESTASHOP_ENDPOINT>
APP_URL=https://myprestashop.com/
WEBSERVICE_KEY=<Webservice_Key>
IMAGE_DOMAIN=<myprestashop.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: {
    WEBSERVICE_KEY: process.env.WEBSERVICE_KEY,
    PRESTASHOP_ENDPOINT: process.env.PRESTASHOP_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 (getproductpage, authenticate, and other parameters). To fetch data from the Prestashop API, you need to use the Fetch function or a library such as Axios.

API Response (The mentioned image demonstrates PrestaShop’s product detail page’s API response):

Screenshot-from-2023-11-03-10-56-26

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 { image_links, name, price, description_short, quantity } = 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]"
                      src={image_links?.image_link?.[0]?.large}
                      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">
                  {name}
                </h1>
                <div className=" mt-3">
                  <p className=" text-sm font-medium text-gray-500">
                    In Stock : {quantity}
                  </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: description_short.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">{price}</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) => {
  const URL = `${process.env.PRESTASHOP_ENDPOINT}/getproductpage?outputformat=json&width=720&id_product=${urlKey}&ws_key=${process.env.WEBSERVICE_KEY}`;
  const response = await fetch(URL, {
    method: "GET",
    headers: {
      "Content-Type": "application/json",
    },
  });
  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

Screenshot-from-2023-11-03-15-32-53

Start Prestashop Headless Development with Webkul.

Happy Coding 🙂

. . .

Leave a Comment

Your email address will not be published. Required fields are marked*


Be the first to comment.

Back to Top

Message Sent!

If you have more details or questions, you can reply to the received confirmation email.

Back to Home