← Back to Blog
E-commerceNext.jsThailand

Building E-commerce with Next.js in Thailand

10 May 2026 · by Yunmin Shin

What Makes Thai E-Commerce Different?

Building an e-commerce site for Thailand requires understanding how Thai consumers shop online. The patterns differ meaningfully from Western markets, and a site built on assumptions imported from a US or European e-commerce playbook tends to underperform even when the code is technically solid.

Thai shoppers heavily research products via LINE, Facebook, and TikTok before purchasing. They prefer to confirm orders via LINE message and pay via PromptPay QR or bank transfer, though cash-on-delivery still accounts for a meaningful share of orders outside central Bangkok, where trust in prepaying an unfamiliar site is lower. Delivery speed expectations are high — same-day delivery is common in Bangkok via services like Lalamove and Kerry Express. Customer service via LINE chat is expected, not optional; a "Contact Us" email form alone reads as a business that's hard to reach.

Your Next.js e-commerce architecture needs to support these patterns from day one, not as an afterthought layered on top of a template built for a different market. This also matters for SEO: most of these stores are still competing against WordPress/WooCommerce incumbents that are slow, plugin-heavy, and poorly indexed on Google.co.th — a fast, properly structured Next.js storefront has a real ranking advantage if it's built correctly from the start.

What Is the Right Architecture?

For most Bangkok e-commerce businesses in the 0–500 orders per day range, this stack works well:

  • Next.js App Router for the frontend and API
  • Supabase (PostgreSQL) for products, orders, inventory, and user data
  • Omise for PromptPay QR and card payments
  • Cloudinary for product image hosting and transformation
  • Upstash Redis for cart sessions and caching
  • LINE Messaging API for order notifications to customers and staff

Avoid overcomplicating the architecture early. A well-built monolith on this stack handles significant traffic before requiring decomposition, and it's far easier to reason about when you're also the one fielding support messages from the store owner on LINE at 9pm about why an order didn't go through.

How Do You Build the Product Catalog?

Structure your database with products, product_variants, categories, and inventory tables. Product variants handle size, color, and other options — each variant has its own SKU, price, and stock level. For businesses selling to both Thai and international customers (common for skincare, supplements, and sourcing-adjacent stores), add a name_th / name_en pair on products rather than trying to force one field to serve both languages — search and filtering work better against dedicated fields than against a single mixed-language string.

Use Next.js generateStaticParams to statically generate product pages at build time. Product pages served from the CDN edge load fast for Bangkok users even on mid-range 4G and are fully indexed by search engines — a real advantage over the client-side-rendered WooCommerce sites still common among Thai SME competitors, whose product pages are often invisible to Google until JavaScript executes. Use revalidatePath to update individual product pages when inventory or pricing changes, without a full rebuild.

How Do You Handle the Cart?

Store cart state in two places simultaneously:

  1. Browser localStorage for immediate, offline-capable access — important given how often a Thai shopper's connection drops mid-session on the BTS or in a building with weak signal
  2. Server-side database or Redis session for persistence across devices and for calculating server-side totals

Always calculate the final order total on the server before processing payment. Never trust client-submitted totals — a savvy user can modify their cart total in the browser.

Cart abandonment recovery works differently here than the email-drip playbook most guides assume. If a customer has opted into your LINE Official Account, a single LINE message reminding them their cart is waiting — sent an hour or two after they leave — gets read far more reliably than an abandoned-cart email, which may sit unopened for days if it's opened at all.

How Do You Implement PromptPay Checkout?

The payment flow for PromptPay:

  1. User clicks "Pay" — your server creates a charge via Omise API and receives a QR code URL.
  2. Display the QR code to the user with a 15-minute countdown timer.
  3. The user opens their banking app, scans the QR, and confirms payment.
  4. Omise sends a webhook to your server confirming the payment.
  5. Your server updates the order status and sends a LINE notification to the customer and the merchant.

Implement the webhook endpoint at a secret URL and verify the Omise webhook signature to prevent fake payment confirmations. Never mark an order as paid based on the client-side redirect alone — only the webhook, since a user can close the browser tab or lose connection right after scanning the QR without the redirect ever firing.

Do You Need to Support Cash on Delivery?

For stores selling outside Bangkok and the other major cities, yes — COD remains a meaningful share of orders for shoppers who don't yet trust an unfamiliar site enough to pay upfront, particularly for higher-value or first-time purchases. Model this as a payment method on the order (payment_method: 'cod') rather than bolting it on as a special case in the checkout flow: the order is created immediately with a pending_cod status instead of waiting on a webhook, and you reconcile payment manually or via your courier's collection report once the parcel is delivered. Keep COD orders in the same orders table and status pipeline as prepaid ones — splitting them into a separate flow tends to create bugs where COD orders silently skip fulfillment steps that prepaid orders get automatically.

How Do You Notify Customers via LINE?

Use the LINE Messaging API to send order confirmation and shipping update messages directly to customers' LINE accounts. Customers opt in by adding your LINE Official Account. The messages feel personal and have significantly higher open rates than email in Thailand — for a lot of Thai shoppers, email is something they check for work, not something they associate with a purchase they just made on their phone.

Send at minimum three LINE touchpoints per order: order confirmation immediately after payment, a shipped notification with the tracking link (Kerry Express and Flash Express both support tracking URLs you can embed directly), and a delivered confirmation that doubles as a soft prompt to leave a review or reorder. Each message should be short — Thai LINE users skim, and a wall of text in an automated message reads as spam even when it's not.

How Do You Optimize Checkout for Mobile?

The overwhelming majority of Thai e-commerce traffic is mobile, often on a mid-range Android phone with a Thai keyboard that takes up nearly half the screen. Keep checkout to as few fields as possible — name, phone, address, and district are usually enough; don't ask for a company name or a second address line unless the business genuinely needs it. Use inputmode="tel" and inputmode="numeric" on phone and postal code fields so the correct keyboard appears automatically, and default to LINE-based identity (via LIFF login) for returning customers so they never have to retype an address they've already given you once.

Ready to Build Something Fast?

Get a free quote. We reply within 24 hours.

Ready to build something fast and scalable?

Get a free project quote. We reply within 24 hours.

Get a Free Quote →