Most small businesses do not need a bigger website. They need the same small website in four languages, online this week, for a price they can say out loud.

That is the whole problem statement behind WebFreesia, a one-person web studio I run in Seoul. Clients come with a Korean brochure site and a deadline, and they need Korean, English, Japanese and Chinese versions that a buyer in Los Angeles or Osaka can actually use — not a Google Translate widget bolted onto the header.

This post is the stack and the process we use to deliver that in 1–5 days, including the parts that are boring on purpose.

The stack

Three tools do most of the work. None of them is exotic, and that is the point: a one-person studio cannot afford a stack that needs a team to babysit it.

  • Readdy AI for the first layout pass. It turns a written brief and a page list into a responsive structure — hero, sections, product grid, contact block — so the first design review happens on real pages instead of a blank canvas.
  • Supabase for content, products and translations. Postgres plus a tiny REST layer means the language switcher is a query parameter, not a separate build.
  • Resend for the things that must arrive: enquiry notifications, quote confirmations, order receipts in the customer's language and timezone.

Everything else is plain Next.js and CSS.

Content model: one page, four languages, no duplicated builds

The mistake that eats the schedule is building four sites. Instead, there is one page record and one translation row per locale.

create table pages ( id uuid primary key default gen_random_uuid(), slug text not null unique, hero_image text, published boolean default false ); create table page_translations ( page_id uuid references pages(id) on delete cascade, locale text not null check (locale in ('ko','en','ja','zh')), title text not null, body text, meta_description text, primary key (page_id, locale) ); 

A page is only published when every locale it claims to support has a row. That single rule kills the classic failure of a site that is English-complete and half-translated in Japanese, which looks worse to an overseas buyer than not having Japanese at all.

Fetching is one query:

export async function getPage(slug, locale) { const { data } = await supabase .from('pages') .select('slug, hero_image, page_translations!inner(title, body, meta_description)') .eq('slug', slug) .eq('page_translations.locale', locale) .eq('published', true) .single(); return data; } 

Locale-aware routing and SEO

A language switcher that keeps the visitor on the same page is table stakes; the part people forget is telling search engines that the four URLs are the same page.

  • Routes are /{locale}/{slug} (/en/pricing, /ja/pricing), so a shared link keeps its language.
  • Every page emits hreflang alternates for all four locales plus x-default pointing at the English version.
  • <html lang> and og:locale follow the active locale; the default is the market you are selling into, not the language of the office.
  • Titles and meta descriptions come from page_translations, not from a template string with the brand name glued on.

The payoff is small but real: when a Japanese buyer searches the product category in Japanese, they land on the Japanese URL instead of being bounced from the English one.

Email that arrives in the right language

Enquiries are the only conversion most of these sites have, so the notification path gets the same care as the page.

await resend.emails.send({ from: 'WebFreesia <hello@webfreesia.com>', to: process.env.STUDIO_INBOX, reply_to: form.email, subject: '[' + locale.toUpperCase() + '] New enquiry from ' + form.name, html: renderEnquiryEmail({ ...form, locale }), }); 

Two details matter more than the template: reply_to is the visitor's address (so answering is one click, not a copy-paste), and the locale travels with the email, so the studio answers in the language the buyer wrote in.

The 1–5 day schedule

Fixed-scope work is what makes the deadline believable. The clock starts after the brief, and each stage ends with an approval before the next begins.

Stage What happens Time
Brief & quote Page list, languages, deadline, then a written fixed quote Same day
Structure & design Sitemap, two homepage directions, one approved 1–2 days
Build & review Responsive build, real-device testing, two revision rounds 2–3 days
Launch & handover Domain, SSL, search registration, recorded admin walkthrough Same day

Landing pages finish in 1–2 days, corporate sites in about 3, and a store with a cart and checkout around 5. The number is a scope decision, not a promise that survives a moving brief.

What it costs, stated plainly

Fixed pricing, quoted in USD, paid through PayPal:

  • Launch, $300: brand introduction site, 5 pages, two homepage directions, domain and SSL, basic admin, 3 months of aftercare.
  • Growth, $700: 12 pages, three design directions, membership and enquiry features, live chat, 3 months of aftercare.
  • Store, $1,150: online store with product variants, cart and checkout, order admin, multilingual rollout.

Extra pages are $100 each, extra languages $350 each, and domain and hosting are billed at cost. Ongoing care after the included period starts at $100/month. No hourly billing, and the scope is in writing before work starts.

Things worth knowing before you copy this

  • AI layout tools are scaffolding, not design. Readdy gets a first pass in front of the client fast; the typography, spacing and mobile behaviour still get hand-fixed. Shipping the generated output as-is is how you get a site that looks like every other generated site.
  • Four languages is a content problem, not a code problem. The code took a day. Collecting and reviewing the Japanese and Chinese copy took the rest.
  • Keep the i18n model boring. One table, one rule, one query. Every clever abstraction I tried first made the handover harder for the client's own admin.

If you are building something similar, or you need the four-language version of your site online this week, the studio site is webfreesia.com/en, and the fastest way to reach me is WhatsApp at +82 10-7904-4659 or email at webfreesian@gmail.com.