Next.js + MUI Starter Version

Trezo Starter Template with Next.js + MUI.

Trezo Starter – How It Works & Multilingual Setup Tutorial

1. Full Version (react-nextjs-material-ui)

Includes 30+ dashboard pages (eCommerce, CRM, PM, LMS, HelpDesk, Analytics, and more). Ideal for developers who want access to all templates and layouts.

2. Starter Version (react-nextjs-material-ui-starter)

A lightweight version with only few page and all configurations (routing, theming, layout, Material UI, etc.) fully set up.

Perfect for buyers who want to start clean and build only the pages they need, such as an LMS or eCommerce system, without having to manually remove all the other pages.

Benefits of the Starter Version:

  • Faster project setup
  • No need to clean unused pages/components
  • Focus on your own features
  • All core configurations (Next.js, Material UI, theme, layouts, etc.) ready to use

Setup Development Environment

To kickstart the development of the web app with Trezo, at first need to setup the react development environment.

  • Node.js and NPM: If NodeJS is not installed then download it from https://nodejs.org. NPM comes bundled with Node.js

NPM Packages

  • Before proceding you'll need to install npm packages. You can do this by running npm install from the root of your project to install all the necessary dependencies.

Development Server

  • Run npm run dev for a dev server. Navigate to http://localhost:3000. The app will autometically reload if you change any of the source files.

Building

  • Run npm run build to build the project. The build artifacts will be stored in the .next/ directory. More Help: Deploying

  • For Static Exports: Run npm run build to build the project. The build artifacts will be stored in the out/ directory. More Help: Static Exports

Local Environment Installation

Open the trezo-nextjs/react-nextjs-material-ui-starter folder in Visual Studio Code and open a terminal on that folder and run these commands one by one.

1. npm install
2. npm run dev
3. Go To http://localhost:3000/en
4. Done

Pages and Components Info

  • eCommerce dashboard (/src/app/[lang]/dashboard/ecommerce/page.tsx)
  • CRM dashboard (/src/app/[lang]/dashboard/crm/page.tsx)
  • Project Management dashboard (/src/app/[lang]/dashboard/project-management/page.tsx)
  • LMS dashboard (/src/app/[lang]/dashboard/lms/page.tsx)
  • Help Desk dashboard (/src/app/[lang]/dashboard/helpdesk/page.tsx)
  • Front page (/src/app/[lang]/page.tsx)
  • Front page features (/src/app/[lang]/front-pages/features/page.tsx)
  • Front page team (/src/app/[lang]/front-pages/team/page.tsx)
  • Front page faq (/src/app/[lang]/front-pages/faq/page.tsx)
  • Front page contact (/src/app/[lang]/front-pages/contact/page.tsx)
  • To Do List (/src/app/apps/[lang]/to-do-list/page.js)
  • and more...

Common Components:

  • Providers (/src/providers/LayoutProvider.tsx)
  • TopNavbar (/src/components/Layout/TopNavbar/index.tsx)
  • LeftSidebar (/src/components/Layout/LeftSidebarMenu.tsx)
  • Footer (/src/components/Layout/Footer.tsx)
  • Control Panel (/src/components/Layout/ControlPanel/index.tsx)
  • and more...

Dependencies

Here are the dependencies list which being used in the react-nextjs-material-ui-starter Template:

"dependencies": {
    "@emotion/cache": "^11.11.0",
    "@emotion/react": "^11.11.4",
    "@emotion/styled": "^11.11.5",
    "@formatjs/intl-localematcher": "^0.6.1",
    "@fullcalendar/core": "^6.1.15",
    "@fullcalendar/daygrid": "^6.1.15",
    "@fullcalendar/react": "^6.1.15",
    "@mui/icons-material": "^7.0.2",
    "@mui/lab": "^7.0.0-beta.11",
    "@mui/material": "^7.0.2",
    "@mui/material-nextjs": "^7.0.2",
    "@mui/x-data-grid": "^8.0.0",
    "@mui/x-data-grid-generator": "^8.0.0",
    "@mui/x-date-pickers": "^8.0.0",
    "@mui/x-tree-view": "^8.0.0",
    "apexcharts": "^4.0.0",
    "boxicons": "^2.1.4",
    "dayjs": "^1.11.11",
    "negotiator": "^1.0.0",
    "next": "^15.0.2",
    "react": "^18.3.1",
    "react-apexcharts": "^1.6.0",
    "react-calendar": "^5.1.0",
    "react-datetime-picker": "^6.0.1",
    "react-dom": "^18.3.1",
    "react-simple-wysiwyg": "^3.1.3",
    "react-svg-worldmap": "^2.0.0-alpha.16",
    "remixicon": "^4.5.0",
    "swiper": "^11.1.4"
},
"devDependencies": {
    "@types/node": "^22.8.6",
    "@types/react": "^18.3.3",
    "@types/react-dom": "^18.3.0",
    "eslint": "^9.14.0",
    "eslint-config-next": "^15.0.2",
    "typescript": "^5.5.2"
}

Fonts Used

By default, the template loads Inter font from Google Web Font Services. The font can be changed based on the website needs. Google Fonts

Font code can be found in the styles/globals.scss & sec/app/[lang]/layout.tsx files.

:root {
  --fontFamily: "Inter", sans-serif;
}

Option to Change the Main Color

styles/globals.scss

:root {
  --primaryColor: #605dff;
  --secondaryColor: #3584fc;
  --successColor: #25b003;
  --dangerColor: #ff4023;
  --warningColor: #ffc107;
  --infoColor: #0dcaf0;
  --lightColor: #f8f9fa;
  --darkColor: #212529;
  --purpleColor: #ad63f6;
  --orangeColor: #fd5812;
}

How to add a New Page & Component?

This guide offers clear, step-by-step instructions for adding a new page to the Trezo Starter Version Next.js + MUI application using the App Router with Multi-Lingual support.

Step 1: Copy the page from (react-nextjs-material-ui)

File path: src/app/[lang]/testimonials/page.tsx

import * as React from "react";
import NextLink from "next/link";
import TestimonialsStyle1 from "@/components/Testimonials/TestimonialsStyle1";
import TestimonialsStyle2 from "@/components/Testimonials/TestimonialsStyle2";
import TestimonialsStyle3 from "@/components/Testimonials/TestimonialsStyle3";
import TestimonialsStyle4 from "@/components/Testimonials/TestimonialsStyle4";
import TestimonialsStyle5 from "@/components/Testimonials/TestimonialsStyle5";
import TestimonialsStyle6 from "@/components/Testimonials/TestimonialsStyle6";
import TestimonialsStyle7 from "@/components/Testimonials/TestimonialsStyle7";
import TestimonialsStyle8 from "@/components/Testimonials/TestimonialsStyle8";
import { getDictionary } from "../../[lang]/dictionaries";

export default async function Page({ params }: any) {
  const { lang } = await params; // Await params to get lang
  const dict = await getDictionary(lang);

  return (
    <>
      {/* Breadcrumb */}
      <div className="breadcrumb-card">
        <h5>Testimonials</h5>

        <ul className="breadcrumb">
          <li>
            <NextLink href={`/${lang}/dashboard/ecommerce/`}>
              <i className="material-symbols-outlined">home</i>
              Dashboard
            </NextLink>
          </li>
          <li>Testimonials</li>
        </ul>
      </div>

      <TestimonialsStyle1 {...dict} />

      <TestimonialsStyle2 />

      <TestimonialsStyle3 />

      <TestimonialsStyle4 />

      <TestimonialsStyle5 />

      <TestimonialsStyle6 />

      <TestimonialsStyle7 />

      <TestimonialsStyle8 />
    </>
  );
}

Following by file path add the link

File path: src/dictionaries/en.json

 "leftSideMenu": [
    {
      "type": "accordion",
      "title": "Extra Pages",
      "icon": "content_copy",
      "accordionPanel": "panel6",
      "subItems": [
        { "title": "Testimonials", "href": "/testimonials/" }
      ]
    },
 ]

File path: src/dictionaries/ar.json

 "leftSideMenu": [
    {
      "type": "accordion",
      "title": "صفحات إضافية",
      "icon": "content_copy",
      "accordionPanel": "panel6",
      "subItems": [
        { "title": "شهادات العملاء", "href": "/testimonials/" }
      ]
    },
 ]

File path: src/dictionaries/fr.json

 "leftSideMenu": [
    {
      "type": "accordion",
      "title": "Pages supplémentaires",
      "icon": "content_copy",
      "accordionPanel": "panel6",
      "subItems": [
        { "title": "Témoignages", "href": "/testimonials/" }
      ]
    },
 ]

Step 3: Copy the Component from (react-nextjs-material-ui)

Copy all related components

File path: src/components/Testimonials

"use client";

import React from "react";
import { Grid, Card, Typography, Box } from "@mui/material";
import Image from "next/image";

const TestimonialsStyle1: React.FC = () => {
  return (
    <>
      <Card
        sx={{
          boxShadow: "none",
          borderRadius: "7px",
          mb: "25px",
          p: { xs: "18px", sm: "20px", lg: "25px" },
        }}
        className="rmui-card"
      >
        <Typography
          variant="h3"
          sx={{
            fontSize: { xs: "16px", md: "18px" },
            fontWeight: 700,
            mb: "25px",
          }}
          className="text-black"
        >
          Testimonials Style - 1
        </Typography>

        <Grid
          container
          columnSpacing={{ xs: 1, sm: 2, md: 2, lg: 3 }}
          spacing={{ xs: 1, sm: 2, md: 2, lg: 3 }}
        >
          <Grid size={{ xs: 12, sm: 6, md: 6, lg: 4, xl: 4 }}>
            <Box
              className="testimonial-item bg-gray border-radius"
              sx={{
                mb: "25px",
                padding: { xs: "20px", sm: "25px" },
                textAlign: "center",
              }}
            >
              <Box mb="10px">
                <Image
                  src="/images/users/user6.jpg"
                  width={100}
                  height={100}
                  alt="user-image"
                  className="rounded-circle"
                />
              </Box>

              <Typography
                variant="h5"
                sx={{
                  fontWeight: "700",
                  fontSize: "18px",
                  marginBottom: "6px",
                }}
              >
                Sarah Johnson
              </Typography>

              <Typography component="span">Financial Manager</Typography>

              <Box
                className="ratings"
                sx={{
                  lineHeight: "1",
                  color: "#fe7a36",
                  fontSize: "16px",
                  my: "15px",
                }}
              >
                <i className="ri-star-fill mr-1"></i>
                <i className="ri-star-fill mr-1"></i>
                <i className="ri-star-fill mr-1"></i>
                <i className="ri-star-fill mr-1"></i>
                <i className="ri-star-fill mr-1"></i>
              </Box>

              <Typography sx={{ lineHeight: "1.8" }}>
                "Statistics is the science of using data to make decisions. This
                is relevant in almost all fields of work and there are many
                opportunities for employment."
              </Typography>
            </Box>
          </Grid>

          <Grid size={{ xs: 12, sm: 6, md: 6, lg: 4, xl: 4 }}>
            <Box
              className="testimonial-item bg-gray border-radius"
              sx={{
                mb: "25px",
                padding: { xs: "20px", sm: "25px" },
                textAlign: "center",
              }}
            >
              <Box mb="10px">
                <Image
                  src="/images/users/user7.jpg"
                  width={100}
                  height={100}
                  alt="user-image"
                  className="rounded-circle"
                />
              </Box>

              <Typography
                variant="h5"
                sx={{
                  fontWeight: "700",
                  fontSize: "18px",
                  marginBottom: "6px",
                }}
              >
                Michael Smith
              </Typography>

              <Typography component="span">Software Developer</Typography>

              <Box
                className="ratings"
                sx={{
                  lineHeight: "1",
                  color: "#fe7a36",
                  fontSize: "16px",
                  my: "15px",
                }}
              >
                <i className="ri-star-fill mr-1"></i>
                <i className="ri-star-fill mr-1"></i>
                <i className="ri-star-fill mr-1"></i>
                <i className="ri-star-fill mr-1"></i>
                <i className="ri-star-half-fill mr-1"></i>
              </Box>

              <Typography sx={{ lineHeight: "1.8" }}>
                "Statistics is the science of using data to make decisions. This
                is relevant in almost all fields of work and there are many
                opportunities for employment."
              </Typography>
            </Box>
          </Grid>
        </Grid>
      </Card>
    </>
  );
};

export default TestimonialsStyle1;

Step 4: It's done!

Now you can browser the page & check

http://localhost:3000/en/testimonials/

How to Translate Component Data?

Step 1: How to translate the TestimonialsStyle1 component data?

First, create the Testimonials Style1 data in dictionaries en.json, ar.json & fr.json

File path: src/dictionaries/en.json

"testimonialsPage": {
    "testimonialsStyle1": [
        {
            "id": 1,
            "name": "Sarah Johnson",
            "position": "Financial Manager",
            "image": "/images/users/user6.jpg",
            "rating": 5,
            "comment": "Statistics is the science of using data to make decisions. This is relevant in almost all fields of work and there are many opportunities for employment."
        },
        {
            "id": 2,
            "name": "Michael Smith",
            "position": "Software Developer",
            "image": "/images/users/user7.jpg",
            "rating": 4.5,
            "comment": "Statistics is the science of using data to make decisions. This is relevant in almost all fields of work and there are many opportunities for employment."
        },
        {
            "id": 3,
            "name": "Emily Brown",
            "position": "Web Developer",
            "image": "/images/users/user8.jpg",
            "rating": 5,
            "comment": "Statistics is the science of using data to make decisions. This is relevant in almost all fields of work and there are many opportunities for employment."
        }
    ]
}

File path: src/dictionaries/ar.json

"testimonialsPage": {
    "testimonialsStyle1": [
        {
            "id": 1,
            "name": "سارة جونسون",
            "position": "مديرة مالية",
            "image": "/images/users/user6.jpg",
            "rating": 5,
            "comment": "الإحصاء هو علم استخدام البيانات لاتخاذ القرارات. هذا الأمر ذو صلة بجميع مجالات العمل تقريبًا وهناك العديد من فرص العمل المتاحة."
        },
        {
            "id": 2,
            "name": "مايكل سميث",
            "position": "مطور برمجيات",
            "image": "/images/users/user7.jpg",
            "rating": 4.5,
            "comment": "الإحصاء هو علم استخدام البيانات لاتخاذ القرارات. هذا الأمر ذو صلة بجميع مجالات العمل تقريبًا وهناك العديد من فرص العمل المتاحة."
        },
        {
            "id": 3,
            "name": "إيميلي براون",
            "position": "مطورة مواقع الويب",
            "image": "/images/users/user8.jpg",
            "rating": 5,
            "comment": "الإحصاء هو علم استخدام البيانات لاتخاذ القرارات. هذا الأمر ذو صلة بجميع مجالات العمل تقريبًا وهناك العديد من فرص العمل المتاحة."
        }
    ]
}

File path: src/dictionaries/fr.json

"testimonialsPage": {
    "testimonialsStyle1": [
        {
            "id": 1,
            "name": "Sarah Johnson",
            "position": "Directrice Financière",
            "image": "/images/users/user6.jpg",
            "rating": 5,
            "comment": "Les statistiques sont la science d'utilisation des données pour prendre des décisions. Ceci est pertinent dans presque tous les domaines de travail et il existe de nombreuses opportunités d'emploi."
        },
        {
            "id": 2,
            "name": "Michael Smith",
            "position": "Développeur de Logiciels",
            "image": "/images/users/user7.jpg",
            "rating": 4.5,
            "comment": "Les statistiques sont la science d'utilisation des données pour prendre des décisions. Ceci est pertinent dans presque tous les domaines de travail et il existe de nombreuses opportunités d'emploi."
        },
        {
            "id": 3,
            "name": "Emily Brown",
            "position": "Développeuse Web",
            "image": "/images/users/user8.jpg",
            "rating": 5,
            "comment": "Les statistiques sont la science d'utilisation des données pour prendre des décisions. Ceci est pertinent dans presque tous les domaines de travail et il existe de nombreuses opportunités d'emploi."
        }
    ]
}

Step 2: Update the page code?

File path: src/app/[lang]/testimonials/page.tsx

import * as React from "react";
import NextLink from "next/link";
import TestimonialsStyle1 from "@/components/Testimonials/TestimonialsStyle1";
import { getDictionary } from "../../[lang]/dictionaries";

export default async function Page({ params }: any) {
  const { lang } = await params; // Await params to get lang
  const dict = await getDictionary(lang);

  return (
    <>
      {/* Breadcrumb */}
      <div className="breadcrumb-card">
        <h5>Testimonials</h5>

        <ul className="breadcrumb">
          <li>
            <NextLink href={`/${lang}/dashboard/ecommerce/`}>
              <i className="material-symbols-outlined">home</i>
              Dashboard
            </NextLink>
          </li>
          <li>Testimonials</li>
        </ul>
      </div>

      <TestimonialsStyle1 {...dict} />
    </>
  );
}

Step 3: Update the component code

File path: src/components/Testimonials/TestimonialsStyle1.tsx

"use client";

import React from "react";
import { Grid, Card, Typography, Box } from "@mui/material";
import Image from "next/image";
import { useParams } from "next/navigation";

interface Testimonial {
  id: number;
  name: string;
  position: string;
  image: string;
  rating: number;
  comment: string;
}

const TestimonialsStyle1: React.FC = ({
  testimonialsPage,
}: {
  testimonialsPage?: any;
}) => {
  const { lang } = useParams();

  const renderStars = (rating: number) => {
    const stars = [];
    const fullStars = Math.floor(rating);
    const hasHalfStar = rating % 1 >= 0.5;

    for (let i = 0; i < fullStars; i++) {
      stars.push(<i key={`full-${i}`} className="ri-star-fill mr-1"></i>);
    }

    if (hasHalfStar) {
      stars.push(<i key="half" className="ri-star-half-fill mr-1"></i>);
    }

    const remainingStars = 5 - stars.length;
    for (let i = 0; i < remainingStars; i++) {
      stars.push(<i key={`empty-${i}`} className="ri-star-line mr-1"></i>);
    }

    return stars;
  };

  return (
    <>
      <Card
        sx={{
          boxShadow: "none",
          borderRadius: "7px",
          mb: "25px",
          p: { xs: "18px", sm: "20px", lg: "25px" },
        }}
        className="rmui-card"
      >
        <Typography
          variant="h3"
          sx={{
            fontSize: { xs: "16px", md: "18px" },
            fontWeight: 700,
            mb: "25px",
          }}
          className="text-black"
        >
          {lang === "en"
            ? "Testimonials Style - 1"
            : lang === "fr"
            ? "Témoignages Style - 1"
            : "أسلوب الشهادات - 1"}
        </Typography>

        <Grid
          container
          columnSpacing={{ xs: 1, sm: 2, md: 2, lg: 3 }}
          spacing={{ xs: 1, sm: 2, md: 2, lg: 3 }}
        >
          {testimonialsPage.testimonialsStyle1.map(
            (testimonial: Testimonial) => (
              <Grid
                size={{ xs: 12, sm: 6, md: 6, lg: 4, xl: 4 }}
                key={testimonial.id}
              >
                <Box
                  className="testimonial-item bg-gray border-radius"
                  sx={{
                    mb: "25px",
                    padding: { xs: "20px", sm: "25px" },
                  }}
                >
                  <Box mb="10px">
                    <Image
                      src={testimonial.image}
                      width={100}
                      height={100}
                      alt="user-image"
                      className="rounded-circle"
                    />
                  </Box>

                  <Typography
                    variant="h5"
                    sx={{
                      fontWeight: "700",
                      fontSize: "18px",
                      marginBottom: "6px",
                    }}
                  >
                    {testimonial.name}
                  </Typography>

                  <Typography component="span">
                    {testimonial.position}
                  </Typography>

                  <Box
                    className="ratings"
                    sx={{
                      lineHeight: "1",
                      color: "#fe7a36",
                      fontSize: "16px",
                      my: "15px",
                    }}
                  >
                    {renderStars(testimonial.rating)}
                  </Box>

                  <Typography sx={{ lineHeight: "1.8" }}>
                    "{testimonial.comment}"
                  </Typography>
                </Box>
              </Grid>
            )
          )}
        </Grid>
      </Card>
    </>
  );
};

export default TestimonialsStyle1;

Step 4: It's done!

Now you can browser the page & check

http://localhost:3000/en/testimonials/

Additional Notes

If you need more details, please refer to the written instructions.

Feel free to reach out to our support team if you have any questions!