Skip to content
Legal Website build

A 224-Page Bilingual Website for a California Law Firm

I designed and built greenacre.law: 224 live pages, a full Spanish mirror, a four-office local structure matched to filing venues, per-page-type structured data, and a URL contract that survived the move intact. Every figure on this page was measured against the live site.

The numbers

Pages live, English and Spanish
224
Legacy URLs resolving, checked live
220 of 220
Homepage HTML, down from 763 KB
34 KB
JSON-LD blocks across the English pages
363
A 224-Page Bilingual Website for a California Law Firm: hero screenshot

02   The breakdown

What Is Live

The sitemap at greenacre.law lists 224 URLs. I fetched every one of them on 6 September 2026 and all 224 answered 200: 112 English pages and a 112-page Spanish mirror, each with a title and a meta description unique within its language, and not one description repeating its page’s title. Greenacre Law is a California property and estates firm with four Southern California offices. I designed and built the site, and my name is in the footer.

The old address book came through the move as well. I checked all 220 rows of the redirect contract against the live domain the same day. Thirty-seven addresses still serve their page at 200. The other 183 return a single 301 to the address they were mapped to. Nothing 404s and nothing chains.

The brief behind all of it was a site that could carry a bilingual practice and four local markets without giving up the addresses the old one already ranked for. That constrains the build more than it sounds. The URL tree came first and the pages were fitted into it, the local page set only widens where Search Console shows demand for the combination, and the Spanish half stayed out of the index until a human had read it.

What Was There Before

The engagement began with an audit. In June 2026 I crawled the 105 URLs the firm’s site had at the time, rendered it in a real browser, ran eight discipline reviews over it, and re-checked every flagged item by hand before writing anything down. The verdict was C+ on 75 verified findings: 5 critical, 27 high, 37 medium, 6 low.

The findings that shaped the rebuild:

  • Structured data was a single hardcoded LegalService block copied onto every page, with areaServed set to the whole United States. No breadcrumb, article, FAQ or person markup existed anywhere on the site.
  • Sixty-two blog posts ran with a meta description that was missing or copied from the title, no author byline, no publication date, and no article markup.
  • Los Angeles and San Diego had a city page with nothing underneath it. Ontario and Carlsbad each had a hub and six nested practice pages, seven URLs apiece. The firm’s two largest markets were the two with no local depth.
  • The homepage shipped 763 KB of HTML.
  • The firm’s own name was misspelled in the filenames across the image library, including the favicon and the social preview image.

The audit also recorded what was working, and the rebuild kept it. The URL tree was carried over instead of redesigned, which is where those 37 unchanged addresses come from. The legal writing on the money pages was already carrying its weight, at 1,823 words on real estate litigation, 1,544 on probate litigation and 1,078 on quiet title, so the rebuild was built to carry that content instead of replacing it.

The Structure

Each of the four offices sits near the courthouse its matters get filed in. Under California Code of Civil Procedure section 392 a real property action is filed where the property sits, which turns an office near a courthouse into a fact a client can check. Each office hub now carries nine pages beneath it: two practice groups and seven practice pages. Los Angeles and San Diego went from one page each to ten. Ontario and Carlsbad went from seven to ten.

Those pages carry their own local material. Thirty-two of the 40 name their filing courthouse and their county recorder by name and address, and the eight that skip both are the practice-group index pages sitting between them. The Los Angeles quiet title page names Stanley Mosk. Ontario names the San Bernardino Justice Center. San Diego names the Central Courthouse and Carlsbad names the North County Regional Center in Vista, which is where a north county real property matter gets filed.

The city matrix stops where the demand stops. The pattern went from six city-and-practice combinations to nine, and the three that were added are the ones with measured city-level demand behind them in Search Console: quiet title, easement litigation and partition actions. Practices with no measured city demand got no new city page. Build the combination only where the query data shows someone searching for it, and stop there.

Above the cities sit the statewide practice pages: nine real estate URLs counting the group page, seven for estate planning, one for business contracts and entity formation. The blog runs 45 URLs, an index, eight topic hubs and 36 articles, with overlapping posts consolidated behind permanent redirects so they stop competing with each other.

The Spanish Half

Every English page has a Spanish counterpart. All 112 Spanish pages return 200, declare lang="es", and carry unique Spanish titles and descriptions. hreflang is reciprocal in both directions with an x-default, and a language control on every page deep-links to the translated version of the page you’re on, so a visitor on a quiet title page lands on the quiet title page in Spanish.

The Spanish site stayed noindex and out of the sitemap for as long as it was unreviewed. It went live on 1 September 2026, after the translation was signed off, and it’s indexable now. The bilingual claim is backed by 112 pages. Until 1 September it was backed by a line in the header.

Schema Per Page Type

The 112 English pages carry 363 JSON-LD blocks between them. I parsed all 363 on 6 September and every one is valid JSON. The census:

BreadcrumbList 111, LegalService 108, FAQPage 82, Article 36, Service 14, CollectionPage 8, Person 2, Blog 1, ItemList 1.

A breadcrumb on every page except the homepage. One Article node per article, all 36 carrying a named attorney author linked by @id to that attorney’s Person node, plus datePublished and dateModified. One CollectionPage per blog topic hub. Per-office LegalService nodes with their own @id, their own address, the number that office answers on and county-level areaServed, each linked to a parent organization node that lists all four offices.

Review markup is deliberately absent. The firm has real Google ratings and the site shows them attributed to the specific office profile they belong to, but no Review or aggregateRating block is emitted. Ratings drift. Markup Google has already cached doesn’t.

Call-First Mobile, and the Compliance Layer

Calls are how this firm’s clients arrive, so the phone path is the primary one. A sticky call element sits on all 112 English pages. Every tel: link carries a data-call-location value naming where on the page it was tapped, seven distinct values on the homepage alone, so a call can be attributed to the utility bar, the header, the hero, body content, the footer, an office address block or the mobile bar.

No JavaScript on the site reads or writes a phone number. Call tracking swaps displayed numbers asynchronously, and a script that rewrites the number on load can win that race and silently break call attribution while the page still looks right. The displayed number is hardcoded in HTML and the call-tracking script is the only thing permitted to change it.

All 112 English pages carry the attorney-advertising disclaimer, which names the site as attorney advertising, states that contacting the firm does not create an attorney-client relationship, asks visitors not to send confidential information before an engagement is agreed in writing, and disclaims any implication about future outcomes. I checked that on all 112. The same 112 pages carry no rating badge and no credential-directory mark of any kind.

Performance and Tracking

Measured with Lighthouse against the live site on 6 September 2026, on the homepage and on a practice page, at mobile and desktop:

  • Accessibility 100 on all four runs.
  • SEO 100 on all four runs.
  • Cumulative layout shift 0 on all four runs.
  • Desktop performance 96 on the homepage, 98 on the practice page.
  • Best Practices 77 on all four runs, which I come back to below.

The homepage HTML is 34 KB uncompressed against the 763 KB the audit measured, and 9.7 KB over the wire. The median English page is 30 KB uncompressed. Fonts are self-hosted and subset to the weights the design uses.

The measurement layer is emitted by the build instead of pasted in at deploy time, which is how it came to be missing from every page of an earlier candidate with nothing reporting it. The tag manager container and the call-tracking script are present on all 224 pages, and the content security policy names every origin they need instead of falling back to allowing inline script.

How It Went Live

Cutover ran off a runbook with eight numbered phases and five marked approval gates, including the deploy itself, the DNS cut and the DNS restore, and a named rollback deployment recorded before every push. The email records were kept out of the blast radius on purpose: only the website record moved, and the mail exchange, sender policy and autodiscover entries were never edited. A website can be rolled back in minutes. Mail that stops arriving at a law firm can’t. After the deploy came a readback against the live domain: indexability, canonicals, sitemap, structured data, headers, caching, redirects landing in one hop, and every call-to-action dialing a tracked number. The post-launch audit found something the plan had missed. The bare domain over HTTPS was serving a shared fallback certificate, so an HTTPS-first browser hit a security interstitial on the firm’s own domain, while the same address over HTTP had been redirecting correctly the entire time and hiding it. A certificate on the apex fixed it. Test the bare domain over 443 explicitly after any cutover that moves only www.

What I Did Not Claim

This is a build write-up. There’s no traffic, ranking or inquiry figure anywhere on this page, and there won’t be one for a while. The English site went live at the end of August 2026 and the Spanish site on 1 September. Organic outcomes on a site this new are noise, and I would be guessing.

Mobile performance is the weak score. Three Lighthouse runs on the homepage came back at 62, 63 and 65, with a largest contentful paint of 9.8 to 10.1 seconds under its simulated throttling, and the practice page scored 62 on its run. Best Practices sat at 77 on every run, on third-party cookies. Both numbers have one cause: the page transfers 898 KiB and 613 KiB of it comes from third-party tags. The document itself is 9.7 KB over the wire. The fix belongs in the tag stack, and it hasn’t been done yet.

Three things from the launch ledger are still open. The firm’s full attorney and staff roster hasn’t arrived, so the team wall stays uncaptioned and there are no individual attorney pages beyond the two founding partners. Forty-six Spanish titles and forty Spanish meta descriptions sit outside the length bands and will truncate in search results until they’re trimmed. Spanish runs about a fifth longer than English and the bands were set in English. And there’s no contact form: the site renders a phone-only path on purpose, and it stays that way until a form processor is approved and proven end to end. A form that silently drops an inquiry loses the client a matter and tells nobody.

If you need a site at this scale designed, built and moved without losing the URLs it already ranks for, tell me what you’re working with.

Ready to talk

Want this kind of breakdown on your account?

Thirty minutes on the phone. One clear set of next steps. Same person on the call as on the work.