0%

Restaurant Website · Bilingual EN/ES

Rockville Brews

A bilingual, prerendered website for a Rockville café and ceviche bar.

Rockville Brews is a global café in Rockville, MD: coffee and paninis by day, fresh ceviche, craft beer, and wine by night. Heading into its August 2026 grand reopening the business had no website at all, so DevMD designed and built one from scratch: a fast, fully prerendered Vue site that ships every page in English and Spanish, reads well on a phone in line at the counter, and lets the owners edit the menu, events, and hours without a CMS.

Live · Managed monthly
Rockville Brews homepage with the hero, navigation, and language switcherLive
ClientRockville Brews (formerly Downtown Brews)
IndustryCafé & restaurant: coffee, craft beer, wine, Latin American and Filipino-inspired food
LocationRockville, MD (Twinbrook)
ProjectBilingual English/Spanish marketing website, built from scratch
ServicesUI/UX design, custom development, Spanish localization, local SEO & structured data, accessibility, ongoing monthly management
StackVue 3 · Vue Router · Vite + vite-ssg · @unhead/vue · hand-written CSS · Vercel
EngagementDesigned, built, and launched in about six weeks for the August 21, 2026 grand reopening. Now managed monthly.

Overview

A first website, built for two audiences and two languages.

Rockville Brews sits at The Alaire at Twinbrook Station in Rockville, MD. Heading into its grand reopening the business had no website of its own, only third-party listings, and the Google Business Profile had nothing to link to. With a rebrand, a refreshed menu, and an ad campaign about to send people to a URL, the site had to read as a real, appetizing, currently open place the moment it loaded.

The café serves two crowds with different clocks, the daytime coffee-and-lunch crowd and the evening ceviche, beer, and wine crowd, and it had to speak to both in English and Spanish. We built it as a fully prerendered Vue 3 site: twelve static HTML pages, six in each language, crawlable without JavaScript, with structured data for local search, a mobile-first layout, and plain, commented data files so the owners can change the menu, events, and hours themselves. DevMD keeps it updated on a managed monthly plan.

Site Walkthrough

A look through the live homepage at rockvillebrews.com.

The homepage moves from a full-bleed hero video that shifts from day to night as you scroll, through the welcome and explore cards, the ceviche feature, the photo gallery, upcoming events and happy hour, to the FAQ.

rockvillebrews.com
Scrolling through the live Rockville Brews homepage
HeroFull-bleed video with a scroll-driven day-to-night color shift and a marquee ticker.
ExploreWelcome copy and three explore cards: the menu, what's on, and how to visit.
CevicheA feature block for the house specialty, made to order.
GalleryReal photography of the plates and pours, with translated alt text.
Events & happy hourUpcoming events that retire themselves, plus the happy hour band.
FAQParking, reservations, gluten-free, and private events, with FAQ schema.

The Menu

A menu that's easy to scan on a phone at the counter.

The menu is where most visitors go after the homepage, and it's the page people read on their phones while they wait in line. Twelve categories, a sticky category bar that tracks where you are, and the happy hour deal placed right where the drinks begin.

rockvillebrews.com/menu
Moving through the live menu page, category by category
Sticky category barA pill bar that sticks under the header, highlights the section in view, and auto-centers the active pill on small screens.
Twelve categories, one fileCeviche to beer & wine, about 45 items, all in one commented data file the owners can edit.
Happy hour in contextThe Monday to Friday, 4–7pm deal sits in a night-toned band right before beer & wine.
Menu schemaA Menu structured-data graph per language, so search engines read the dishes too.
PDFs and the fine printDownloadable food and drinks menus, plus the raw-food notice in both languages.
Tags that can't driftSignature, popular, seasonal, iced: a fixed set of labels translated in one place.

Hablamos Español

Two complete language trees, not a translation widget.

Rockville's community is bilingual, so the site is too. Every page has a Spanish twin under /es with its own URL, title, description, and structured data. Drag the handle to compare the same page in both languages.

Rockville Brews Home page in Spanish
Rockville Brews Home page in English
EnglishEspañol

Home: English vs. Español — drag to compare, scroll inside to see the whole page

rockvillebrews.com/es
Switching languages in place: the URL, the html lang attribute, the metadata, and every string follow

Detected before first paint

A tiny inline script runs before the app boots: a Spanish-language browser lands on /es without ever seeing an English frame, and an explicit EN/ES choice from the switcher is remembered on every later visit.

Two real URL trees

Every page lives at / and /es with matching hreflang tags, localized canonicals, and a sitemap that lists all twelve URLs with their reciprocal alternates.

100% coverage

All 165 interface strings and 116 content fields, from menu notes and event copy to FAQ answers, image alt text, and the legal disclaimer, have Spanish versions, with English as an automatic fallback for anything left blank.

Localized SEO

The html lang attribute, titles, descriptions, Open Graph locale, and the Menu and Event schema all follow the page language, so each language can rank on its own.

Written for the layout

Spanish runs 15–25% longer, so headlines were rewritten rather than translated literally, and a handful of :lang(es) rules keep the hero and the happy hour band from wrapping.

A switcher that respects the visitor

Two real links, not a toggle: it keeps your place (including anchors on the menu), works with middle-click and new tabs, and reads as "English" and "Español" to screen readers.

Mobile Walkthrough

Built for the phone in line at the counter.

Most visits happen on a phone, so the layout is mobile-first: a full-screen menu that slides down from the top, a category bar you can thumb through, 44px touch targets, and a lighter hero video on small screens. Each phone below auto-scrolls the real mobile layout of the live site.

Rockville Brews Home page on mobileRockville Brews Home page with the mobile navigation open
Home
Rockville Brews Menu page on mobile
Menu
Rockville Brews Visit page on mobile
Visit
Mobile-first breakpointsLayouts start single-column and grow at 720, 820, 900, and 1040px; the menu becomes two columns and the gallery three.
Height-aware heroExtra media queries for short laptop and landscape-phone screens keep the headline and the call to action on screen together.
Lighter on small screensA 720p hero video under 900px, no video under reduced motion or data saver, lazy images with real dimensions, and 44px touch targets.

What the Site Brings

The pieces that make it feel like a real, open place.

Prerendered and crawlable

Twelve static HTML pages; nothing essential depends on JavaScript, and a noscript block still carries the address, hours, and a menu summary in the page language.

Events that retire themselves

Events carry real dates and drop off the day after they end, at build time and again in the browser, so the site never advertises last month's tasting. One list feeds the teaser, the events page, the landing popup, and the Event schema.

Landing event popup

A once-per-session dialog for the featured event, closable with Escape or a click outside, that deep-links to the event in the visitor's language.

Owner-editable content

Menu, events, happy hour, hours, FAQ, gallery, and press live in plain, commented data files: no CMS login, no database, nothing to keep patched.

Local SEO and structured data

Restaurant and café, Menu, Event, and FAQ schema, geo meta, Open Graph cards, robots rules, and a sitemap, with no ratings copied into the schema, per Google's rules.

Accessible by design

A Section 508 / WCAG AA pass: visible 3px focus rings, AA-safe text colors, a skip link, proper heading structure, focus-trapped dialogs, and reveal animations that degrade to plain content.

Hero video, day to night

A full-bleed video hero with a scroll-driven day-to-night color shift, served in two sizes and paused whenever it leaves the screen.

Hours and happy hour, defined once

Opening hours and the happy hour deal are written once and reused in the footer, the FAQ, the visit page, the menu band, and the business schema.

Coming-soon gate with a private preview

One environment flag swaps the whole site for a holding page; a private preview link unlocked the real build for the owners before launch.

A warm, coherent design system

Design tokens for an espresso-and-gold palette, Cormorant Garamond display type with DM Sans body, and a cool "night register" used only for the evening side of the brand.

Issues & Solutions

The real problems we hit, and how we solved each one.

Shipping two languages from a static build, keeping a video hero light on phones, and launching a site the public couldn't see yet all came with their own snags. Here's what came up, grouped by where it lived in the build.

Localization

An i18n library that leaked between pages

Issue

The site is prerendered with vite-ssg, which renders all twelve routes in one Node process. A conventional module-level i18n instance shares state across those renders, so a locale set while rendering /es/menu could bleed into whatever page rendered next.

Solution

We wrote a ~120-line localization layer instead of installing one. The locale is a pure function of the URL, the dictionary is picked per render, blank Spanish strings fall back to English, and the dev server warns about any key still in English.

A flash of English for Spanish speakers

Issue

Redirecting to /es after the app boots would mean hydrating English markup, then swapping every string, the URL, and the html lang attribute after first paint.

Solution

A small inline script runs before anything paints: it honors an explicit EN/ES choice from the switcher on every visit, otherwise checks the browser language exactly once, and redirects with replace() so the back button still works. URLs that already name a language are never touched.

Spanish is 15–25% longer

Issue

Literal translations pushed the hero headline to five lines, wrapped the five-item navigation, and broke the happy hour band.

Solution

Strings were rewritten for the space rather than translated word for word, the nav uses "Prensa" instead of "Noticias", a deliberately tiny :lang(es) block relaxes a few widths, and the mobile overlay nav kicks in at 1040px instead of 860px.

Two languages, one HTML template

Issue

Every prerendered page shares one index.html, so the noscript fallback and keywords meta were English on Spanish pages, and noscript can't become a Vue component without a hydration mismatch.

Solution

A build step rewrites those two blocks on every /es page after Vue has rendered it, while titles, descriptions, canonicals, hreflang, og:locale, and Menu schema are generated per language on each page.

Keeping both trees discoverable

Issue

Google drops hreflang pairings that aren't reciprocal, and two menu pages claiming the same structured-data identity get merged or dropped.

Solution

The sitemap lists all twelve URLs with their full alternate set, including themselves and x-default, and the Menu schema gets its own @id and inLanguage per locale.

Mobile & performance

A hero video that could hurt first paint

Issue

A full-bleed autoplay video is heavy, and iOS in Low Power Mode refuses to autoplay even muted, inline video.

Solution

The video ships with no src and preload="none"; the right file (720p under 900px wide, 1080p above) is attached after mount, skipped entirely under reduced motion or data saver, paused when it leaves the viewport, and retried once on the first touch or scroll for iOS.

Short laptops hid the call to action

Issue

The hero stack measured about 803px tall regardless of viewport, so laptops shorter than that showed the headline and no button.

Solution

Height-based media queries (under 872px and under 640px tall, width-guarded so portrait phones keep the width-driven scale) tighten the hero spacing and type so the headline and the CTA always share the screen.

Twelve categories on a phone

Issue

A long menu is hard to navigate on a small screen, and using scrollIntoView on the category pill bar yanked the whole page vertically mid-scroll.

Solution

A sticky, horizontally scrollable pill bar with a throttled scrollspy; the active pill is centered by scrolling only the bar, never the page, and anchors account for the header and bar heights.

Keeping the bundle small

Issue

The first prototype used Three.js for an animated hero, which dominated the bundle for a decorative effect.

Solution

Three.js was dropped for a video hero plus CSS, and route components load on demand. The shipped app is about 68 kB of JavaScript and 8 kB of CSS gzipped, plus route chunks of 0.5–2 kB.

Launch & operations

Reviewing the site before anyone could see it

Issue

The owners needed to review the real site on the real domain while the public still saw a holding page.

Solution

A single environment flag swaps the app for a coming-soon page. A private ?preview= link unlocks the full site for that browser session, strips the token from the URL so it can't leak into analytics or screenshots, and shows a preview bar with an exit button.

Events that go stale

Issue

Restaurant sites are notorious for advertising last month's event, and a build running in UTC would even retire an Eastern-time event at 8pm.

Solution

Each event carries ISO dates with their own time zone offset; the list is filtered at build time and again in the browser, so a long-lived deploy self-corrects and nothing expired ever shows.

Looking legitimate without inventing proof

Issue

A brand-new site with an ad campaign behind it has to read as real and currently open, but copying Google ratings into schema violates Google's policies, and there were no testimonials to use.

Solution

Trust comes from structure instead: complete business, menu, event, and FAQ schema; the real address, hours, phone, and map; real photography; and links to the Google, Yelp, and Instagram listings. No invented reviews or ratings.

Clean URLs that 404'd

Issue

The prerender emits menu.html while the router and every link use /menu, so direct visits and refreshes on sub-pages 404'd on the host.

Solution

Vercel's cleanUrls setting maps each route to its HTML file, and the project README documents why that one line is load-bearing.

Results

What the café walked away with.

A first web presence for the business, launched in time for the grand reopening.
Every page available in English and Spanish from day one, each with its own URL and search metadata.
Twelve fully prerendered, crawlable pages with Restaurant, Menu, Event, and FAQ structured data.
A mobile-first experience built for the phone in line at the counter.
Owners update the menu, events, hours, and FAQ in plain data files, with DevMD handling changes on a managed monthly plan.
Section 508 / WCAG AA accessibility and a light, fast build.

Tech Stack

The pieces behind the build.

Vue 3Vue RouterVite + vite-ssg@unhead/vueCustom i18nCSS design tokensJSON-LDVercelGoogle Fonts

Vue 3

Component-based front end with script setup; six page components, each rendered in both languages.

Vite + vite-ssg

Static prerendering of all twelve routes into plain HTML at build time, hydrated on the client.

Vue Router

One page table generates both language trees, with clean URLs on Vercel.

@unhead/vue

Per-page titles, descriptions, canonicals, hreflang, Open Graph, and JSON-LD that follow the page language.

Custom i18n layer

About 120 lines: URL-derived locale, per-render dictionaries, English fallback, and a dev-time missing-key report.

Hand-written CSS and design tokens

One tokens file and one stylesheet, no framework, with AA-safe color tokens and a night register for evening surfaces.

Structured data and local SEO

Restaurant and café, Menu, Event, and FAQ schema, geo meta, and a sitemap with reciprocal hreflang.

Vercel

Static hosting with clean URLs, preview deployments, and Vercel Analytics.

Google Fonts and Maps

Cormorant Garamond and DM Sans with preconnect and swap, plus a keyless, lazy Google Maps embed on the Visit page.

Editable data files

Menu, events, hours, happy hour, FAQ, gallery, and press as commented JavaScript, no CMS.

Let's Build

Need a bilingual, mobile-first site for your restaurant or café?

DevMD designs and builds fast, accessible websites that read well in every language your customers speak, and keeps them updated so your menu, hours, and events are never out of date. Tell us about your place and we'll propose the right build path.