Nings Is



Overview
Nings Is is the customer-facing ordering and marketing website for Nings, a Thai restaurant in Reykjavik. The site lets visitors browse the menu, customise dishes, place catering and company orders, read hygiene information, find locations, and order for pickup or delivery in Icelandic.
Following the VISKA customer pattern, Prismic manages all marketing content, while the ordering side — catalog, pricing, cart, and checkout — runs on the shared Upsell platform through @upsell/kit and the public-api.upsell.is/v2 API. There is no local database: Prismic is the content source, and SWR (via the kit and a few direct hooks) handles client-side data fetching. The site is Icelandic-only (single locale) and deployed to Vercel.
Tech Stack & Rationale
Layer | Technology | Why |
|---|---|---|
Framework | Next.js 14 (App Router), React 18 | Server-first rendering with route groups ((main), (clean), (prismic)) |
Language | TypeScript | Strict typing across slices, kit types, and API responses |
Styling | Tailwind CSS 3.4 | Rapid, consistent brand styling |
CMS | Prismic + Slice Machine | Editors manage pages, layout, shipping, and slices without code changes |
Client data fetching | SWR 2.2 (via @upsell/kit + direct hooks) | Revalidation and caching for cart, catering cart, and client state |
Business logic | @upsell/kit + public-api.upsell.is/v2 (Axios) | Shared cart, checkout, and Apple Pay logic with a MobileApp-authenticated store ID |
Forms & email | Formik + Yup, SendGrid | Catering/company/contact form submissions |
Animation | GSAP, Swiper, Slick, Framer Motion | Hero motion and carousels |
Monitoring | Sentry | Error tracking in production |
Hosting | Vercel | Preview + production deployments via Nx |
Architecture
A request flows through server-rendered pages, then hands off to SWR-backed client components that talk to the Upsell API. Prismic content is fetched server-side with tag-based caching and preview support.
The flow runs: Browser request (/menu) → Server Components (main) · (prismic) → Client components (cart · customizer) → SWR hooks (client revalidation) → public-api (upsell.is/v2) → SendGrid (catering email); Browser request (/menu) → Server Components (main) · (prismic) → Prismic client (tag cache + preview) → @upsell/kit (cart · checkout).
- Server rendering — (main) pages (menu, stadirnir locations, great-additions) and (prismic) pages are React Server Components that fetch Prismic pages documents (with their linked layouts document) through a tag-cached client, then render the slice zone.
- Client interactivity — the dish customizer, cart, and upsell ("great additions") hydrate into client components that read the product catalog through @upsell/kit, with SWR managing revalidation and optimistic cart state.
- Catering & company orders — catering and company carts are persisted to local storage (lib/cateringCart.ts, lib/companyCart.ts) and submitted through form slices with SendGrid email.
- Checkout — the (clean) group renders the checkout funnel (shipping, summary, verification, success); payment goes through the Upsell API with Apple Pay via useApplePay and OTP verification via react18-input-otp.
- Legacy redirects — the next.config.js keeps old WordPress asset URLs (e.g. the nutrition PDF) redirected to their Prismic-hosted replacements.
Folder Structure
customers/nings-web/
├── app/(routes)/
│ ├── (main)/ # menu · stadirnir (locations) · great-additions
│ │ ├── (customization)/ # products/[productID], deals/[dealID]
│ │ ├── login/ · profile/order/[id]
│ ├── (clean)/checkout/ # shipping · summary · success · verification
│ ├── (prismic)/[[...slug]]/ # CMS-driven pages + slice-simulator
│ ├── buttons/
│ └── layout.tsx
├── components/ # auth, cart, checkout, deal, input, menu, product, profile, store…
├── contexts/ # DealContext, TopBannerContext, layout
├── slices/ # 26 slices (Hero, AboutHero, HygieneInfo, CateringForm, …)
├── customtypes/ # layouts, pages, shipping_setup, top_banner, variation_setup
├── constants/ # branches, cart, checkout, customization, menu, order, shipping
├── lib/ # api.ts, cateringCart.ts, companyCart.ts, sendEmail.ts, hooks/
├── app/layout.tsx · prismicio.ts
└── next.config.js · tailwind.config.tsContent Model
Prismic is the single content source. Five custom types drive the site:
Custom type | Kind | Purpose |
|---|---|---|
pages | Repeatable | Marketing pages — uid, page_title, a layout link, a slice zone, and SEO metadata (meta_title, meta_description, meta_image) |
layouts | Repeatable | Site chrome composed of navbar, children, and footer slices; linked from each pages document |
top_banner | Singleton | An optional promo bar (paragraph, cta_text, cta_url, active) surfaced by the TopBannerContext |
variation_setup | Singleton | Variation attributes — an attributes Group (attribute_id, attribute_name, image, secondary_image, calories) |
shipping_setup | Singleton | A single disable_delivery toggle that gates the delivery option |
The pages slice zone exposes 21 slices, notably hero, about_hero, hygiene_hero/hygiene_info/hygiene_spices, catering_hero/catering_selection/catering_form/catering_faq, deal_section, location_section, map_with_text, article, and the form slices contact_us_form, career_form, and contact.
Impact & Results
- In production for the Nings Thai restaurant in Reykjavik, with catering/company orders and hygiene information.
- One of 16+ customer sites served by the shared VISKA monorepo platform.
My Contributions
Worked on the Nings site as part of the VISKA monorepo team:
- Initiated the Nings web project and built out its home page and menu.
- Built the contact form and the dish customization page.
- Implemented the deal-category hero, the mobile home menu, and the "great additions" upsell page.
- Iterated on the site with a round of UI improvements.
References
[1] Nings, "Nings.is — Thai restaurant," nings.is, 2025. [Online]. Available: https://nings.is
[2] Vercel, "Next.js Documentation," nextjs.org. [Online]. Available: https://nextjs.org/docs
[3] Prismic, "Prismic Documentation," prismic.io. [Online]. Available: https://prismic.io/docs
[4] Vercel, "SWR — React Hooks for Data Fetching," swr.vercel.app. [Online]. Available: https://swr.vercel.app
[5] Tailwind Labs, "Tailwind CSS Documentation," tailwindcss.com. [Online]. Available: https://tailwindcss.com/docs
Comments
Leave a Comment
You must be signed in to comment
0 Comments
No comments yet. Be the first to comment!