AV
HomeAboutProjectBlog

© 2026 Ave syah Shina. All rights reserved.

  1. Home
  2. Projects
  3. Localsalad.is

Localsalad.is

January 5, 20254 min read
View Project
Next JsTypescriptTailwind CSSSWRPrismic
1 / 3

Overview

Localsalad.is is the customer-facing ordering and marketing website for Localsalad, an Icelandic salad restaurant chain. The site lets visitors browse the menu, customise a salad, check the nutritional breakdown of every item, order for pickup or courier delivery, place company orders, subscribe to the newsletter, and find branches on a map — all in Icelandic or English.

The site follows the standard VISKA customer pattern: Prismic manages the marketing content and menu, while the product catalog, pricing, cart, and checkout come from the shared Upsell platform via @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) handles client-side data fetching.

Tech Stack & Rationale

Layer

Technology

Why

Framework

Next.js 14 (App Router), React 18

Server-first rendering with locale-based route groups ((main), (clean), (plain), (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, and slices without code changes

Client data fetching

SWR 2.2 (via @upsell/kit)

Revalidation and caching for cart, checkout, 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

i18n

LinguiJS (is, en) + Crowdin

Compile-time message catalogs, Icelandic-first locale redirect

Maps

Mapbox GL + react-map-gl

Branch locator

Forms & email

SendGrid + newsletter route

Company/contact forms and the newsletter endpoint

Animation

GSAP, Swiper, Framer Motion, Lottie

Hero motion and carousels

Monitoring

Sentry

Error tracking in production

Hosting

Vercel

Preview + production deployments via Nx

Architecture

A request flows from the locale middleware 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 (/is/menu) → middleware.ts (locale redirect → is) → Server Components (RSC + generateMetadata) → SWR hooks (client revalidation) → public-api (upsell.is/v2) → Vercel (edge / CDN); Browser request (/is/menu) → middleware.ts (locale redirect → is) → Prismic client (tag cache + preview) → @upsell/kit (cart · checkout).

  1. Locale routing — middleware.ts reads the request pathname and, when no locale prefix is present, redirects to /is/... (Icelandic default). API and well-known paths are exempt.
  2. Server rendering — (main) 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.
  3. Client interactivity — interactive features (cart, salad customizer, nutrition calculator, deals) hydrate into client components that read the product catalog through @upsell/kit, with SWR managing revalidation and optimistic cart state.
  4. Checkout — the (clean) group renders checkout steps (shipping, summary, verification) and the (plain) group renders the success page; payment goes through the Upsell API with Apple Pay via useApplePay and OTP verification via react18-input-otp.
  5. Newsletter — a dedicated /api/newsletter route persists signups, while company/contact form slices submit through the platform.

Folder Structure

customers/localsalad-web/
├── app/[locale]/
│ ├── (main)/
│ │ ├── (customization)/ # products/[productID], deals/[dealID]
│ │ ├── store/ · login/ · profile/
│ ├── (clean)/checkout/ # shipping · summary · verification
│ ├── (plain)/checkout/success/
│ ├── (prismic)/[[...slug]]/ # CMS-driven pages + slice-simulator
│ └── layout.tsx
├── components/ # auth, cart, checkout, deal, input, menu, product, profile, store…
├── contexts/ # TopBannerContext, layout
├── slices/ # 16 slices (Hero, Menu, Branches, NutritionalInformation, …)
├── customtypes/ # pages, layouts, top_banner
├── constants/ # branches, customization, order, products
├── lib/ # api.ts, generateMetaData.ts, sortBranches.ts, hooks/
├── locales/translations/ # en.po, is.po (Crowdin)
├── middleware.ts · appRouterI18n.ts · prismicio.ts
└── next.config.js · tailwind.config.ts

Content Model

Prismic is the single content source. Three 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, meta_keywords)

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

The pages slice zone exposes 13 slices: hero, menu, special_product, card_grid, branches, text_image, two_cols_content, banner, nutritional_information, paragraph, and the form slices contact_form and company_form.

Impact & Results

  • In production for the Localsalad salad chain in Iceland, with nutrition details, company orders, and newsletters.
  • One of 16+ customer sites served by the shared VISKA monorepo platform.

My Contributions

Worked on the Localsalad site as part of the VISKA monorepo team:

  • Added the shopping-bag flow and improved the menu (deals view on the menu, the deals page, and menu navigation).
  • Built the nutrition experience: the nutritional page, the nutrition modal, nutrition quantity handling, and the nutrition scroll fix.
  • Added the newsletter and email form, the SMS-info notice, and the reply-to field on the contact form.
  • Improved the hero and branch map, added products to categories, and ordered branches with the sortBranches utility.
  • Set up Crowdin for translations, completed the Icelandic catalog, and fixed the included-items and success-page issues.

References

[1] Localsalad, "Localsalad.is — Salatbar," localsalad.is, 2025. [Online]. Available: https://localsalad.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] LinguiJS, "LinguiJS — Internationalization," lingui.dev. [Online]. Available: https://lingui.dev

Comments

Leave a Comment

You must be signed in to comment

0 Comments

No comments yet. Be the first to comment!