Gold Label Technology Limited Offical Website

A request-for-quote (RfQ) system for Gold Label Tech Ltd. Using Next.js with Prisma and MariaDB. Enhance on SEO with SSR and also include Admin page for managing the RfQs.

Features

  • Theming: Support for Dark/Light mode.
  • Localization (i18n): Support for English and Traditional Chinese and Simplified Chinese locales.
  • Admin Page(jwt): Contain an Admin Page for editing the items data and other features control.
  • Shopping Cart: Contain a shopping cart for user to add and modify the items.
  • SEO Handling: Support SEO optimization across diffferent language and platform.

Technology

  • Next.js 14
  • TailwindCSS
  • Next UI
  • TypeScript
  • MariaDB
  • Prisma
  • Next-Auth with JWT
  • SSR (Server Side Rendering)

Development Insights

  • Challenge: Page Compile Speed is Slow

    • SSR means that the page will render on the server, so if the server is not completing rendering quickly, the visitor will see an empty blank page when accessing the website. Therefore, compile speed is a critical problem. As I was building some Nuxt3 applications, I did not know that Next.js can directly access the database in Server Components. Finally, I fetch data directly in the server-side component, and the compile speed decreased. Now, the page can open in less than 100ms. (While other stuff just make them CSR 😏)
  • Challenge: Reusable Data with Cached Data Fetching

    • From the above, I have figured out that I can directly access the database to get the items data, but there is still a problem. The generateMetadata function provided by Next.js and the main Page function are running asynchronously, which means I need to call the database twice to get the items data: once for the metadata and once for the page. So I learned that I can use caching to store the data and reuse it in both functions, which also speeds up the page compile time!
    const getData = cache(async (productName: string) => {
            const product = await prisma.product.findFirst({
                where: { item_code: productName },
                select: {
                    id: true,
                    item_code: true,
                    name: true,
                    youtube_link: true,
                    features: true,
                    spec: true,
                    product_types: { select: { id: true, name: true } },
                    categories: { select: { id: true, name: true } },
                    images: {
                        select: { id: true, url: true, order: true },
                        orderBy: { order: 'asc' },
                    },
                    attachments: {
                        select: { id: true, file_path: true, type: true },
                        orderBy: { order: 'asc' },
                    },
                    // attachments: true,  // To select all fields
                },
            })
            // Check if product is not found
            if (!product) {
                redirect(`/products/1`)
            }
        return { product_data: product }
    })