Local SEO for dental clinics: Google Business Profile + schema.org that works
Clinic in Bela Vista, São Paulo. When Google said “dentist Bela Vista”, it appeared in position 8. When a patient came, they’d ask if it was a referral from someone they knew. Nobody arrived from search.
I implemented the complete combo: optimized Google Business Profile, consistent NAP across all platforms, correct schema.org on the site, 360-degree photos of the office, aggressive review collection.
90 days later: position 1 in “dentist Bela Vista”, “implant in Bela Vista”, “dental cleaning Bela Vista”. Office went from 6-7 new patients per month to 12-15.
This isn’t magic. It’s execution. I’ll show you exactly what I did, step by step. Replicable in any dental clinic in Brazil.
Why Local SEO matters for dentistry
Dentistry is 100% local. Patient won’t travel across the city for a cleaning. When someone types “dentist [your neighborhood]”, they’ve decided: they want to go nearby.
Google understands this. 70% of searches for “dentist [your neighborhood]” look at 3 local results (positions 1-3). If you have your site optimized for Local SEO, 50-60% of those clicks will land on your site.
Competition is smaller than national SEO. You have to beat 3-5 local clinics, not 1000 national websites.
Investment is low: R$ 0 if you do it yourself, R$ 500-1k if you hire someone to structure it.
ROI is astronomical. A clinic in Bela Vista with average ticket of R$ 500-800 per first consultation gains R$ 6-12k per month in new revenue with 10-15 patients.
The anatomy of local ranking (what Google sees)
Google puts 3 factors at the top for Local SEO:
- Google Business Profile (GMB): the profile is 40-50% of the weight. Complete, updated, many reviews.
- NAP consistency: Name, Address, Phone in all places (Google, Bing, Yellow Pages, site). Google detects inconsistency and penalizes.
- Schema.org on site: data structure that tells Google “here’s a clinic, here’s my phone, hours, specialty”. Without this, Google has to guess.
- Local links: citations on relevant directories (Jameda, Doctolib, Dental Association).
- Reviews: quantity, recency, response to criticism. Site with 30 5-star reviews ranks better than site with no reviews.
Top 3 (GMB, NAP, schema) are 70% of the work. Start there.
Step 1: Impeccable Google Business Profile
You probably already have a GBP. But it’s incomplete. Let me show you the checklist.
Essential (50% of impact)
Main category: dentistry has several. Pick the one that fits most:
- “Dental Office” (generic, less competitive)
- “Dental Clinic” (same)
- “Implant Clinic” (specific, more competitive)
If you do implants, choose “Implant Clinic”. If you do general, “Dental Office”.
Secondary categories: add 2-3. Examples:
- Teeth Cleaning
- Teeth Whitening
- Orthodontics
Cover photo: a photo of the office, not your hand. Professional photo, good lighting, no patients. Minimum 1080x608px. Update every 6 months.
Photos: upload 10-15 photos. Office, waiting room, chair, patients (with consent), before/after smile (anonymous). Organize in albums by theme.
Videos: upload 1-2 short videos (30-60s). Dentist introduction, office tour. Videos in GBP increase clicks by 35% according to Google.
Company description: max 750 characters. Not “best clinic in the world”. It’s specific:
Bad: “We are a clinic of excellence dedicated to your smile”. Good: “Dental office in Bela Vista with implant specialty. We serve adults and children. Parking available. Interest-free treatment financing”.
Add local keywords (“Bela Vista”, “implant”, “financing”) naturally.
Hours of operation: put correct, including Saturday if you work. GBP penalizes if site says one time and GBP says another.
Phone: your main number. If you receive calls on WhatsApp, put the same number (Google understands).
Website: your domain.
Attributes: add all that apply:
- Accepts card
- Accepts medical insurance (if you do)
- Parking
- WiFi
- Play area for children (if applicable)
Each attribute can increase CTR by 5-10%.
Advanced (20% of impact)
Questions and Answers: customers ask questions on GBP. Answer in less than 24 hours.
Example: “Do you accept insurance XYZ?” Answer: “Hi! Yes, we accept insurance XYZ. To check your specific coverage, call (11) 9999-9999 or WhatsApp”.
Each answer given improves ranking.
Posts: publish 2x per month on GBP.
Example 1: “Are you brushing your teeth correctly? Watch our tutorial video on YouTube”. Example 2: “This week we have a promotion: cleaning + digital X-ray for R$ 89. Take advantage!”.
Posts with photos or videos generate 23% more clicks.
Offers: create 2-3 offers per quarter:
- “First appointment + X-ray: R$ 0”
- “New patients: 10% off”
- “Orthodontics: finance in 24x interest-free”
Offers increase leads by 40% (according to Google’s internal data).
Step 2: Consistent NAP everywhere
NAP: Name, Address, Phone. Has to be identical in ALL of these places:
- Google Business Profile
- Clinic website (footer, contact page)
- Bing Places (exists, but very little competition. Still, keep it equal)
- Yellow Pages (Brazilian version, some people still use)
- Professional Association (Federal Council of Dentistry, if registered)
Common errors I see:
-
Site: “Vitória Dental Office - Bela Vista - SP”
-
GBP: “Vitória Dental Clinic”
-
(different name = Google thinks they’re two different businesses)
-
Site: “Rua das Flores, 123 - Bela Vista - São Paulo - SP”
-
GBP: “Rua das Flores 123, Bela Vista, São Paulo - SP”
-
(missing hyphen, different formatting = inconsistency)
-
Site: “(11) 3333-3333”
-
GBP: “+55 11 3333-3333”
-
(different formatting of same number = inconsistency)
Tool to verify: Moz Local. Costs R$ 300/year, but gives you a report of NAP inconsistency across all platforms. Worth it.
If you don’t want to pay, do it manually:
- Create spreadsheet
- Note the name in each platform (GBP, site, Yellow Pages)
- Make it equal everywhere
Step 3: Schema.org on site
Schema is the “dictionary” you leave for Google. Without schema, Google reads your site as text. With schema, Google reads as structured data.
Your clinic should have LocalBusiness + MedicalBusiness + Dentist + AggregateRating schema.
Here’s the JSON-LD to copy in the site’s <head>:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Dentist",
"name": "Vitória Clinic",
"image": "https://clinic.com/office-photo.jpg",
"description": "Dental clinic in Bela Vista with implant specialty. We serve adults and children. Parking. Interest-free financing.",
"url": "https://clinic.com",
"address": {
"@type": "PostalAddress",
"streetAddress": "Rua das Flores 123",
"addressLocality": "São Paulo",
"addressRegion": "SP",
"postalCode": "01234-567",
"addressCountry": "BR"
},
"telephone": "+55 11 3333-3333",
"openingHoursSpecification": [
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": "Monday",
"opens": "09:00",
"closes": "18:00"
},
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": "Tuesday",
"opens": "09:00",
"closes": "18:00"
},
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": "Saturday",
"opens": "09:00",
"closes": "13:00"
}
],
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.8",
"reviewCount": "32"
},
"review": [
{
"@type": "Review",
"reviewRating": {
"@type": "Rating",
"ratingValue": "5"
},
"author": {
"@type": "Person",
"name": "João Silva"
},
"reviewBody": "Excellent service, very professional. I recommend!",
"datePublished": "2026-05-01"
}
],
"hasMap": "https://maps.google.com/?q=Rua+das+Flores+123+Bela+Vista+Sao+Paulo"
}
</script>
If you use Astro, put it in a component:
---
// src/components/LocalBusinessSchema.astro
export interface Props {
name: string;
phone: string;
address: string;
city: string;
state: string;
zipCode: string;
rating: number;
reviewCount: number;
}
const { name, phone, address, city, state, zipCode, rating, reviewCount } = Astro.props;
const schema = {
"@context": "https://schema.org",
"@type": "Dentist",
"name": name,
"telephone": phone,
"address": {
"@type": "PostalAddress",
"streetAddress": address,
"addressLocality": city,
"addressRegion": state,
"postalCode": zipCode,
"addressCountry": "BR"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": rating.toString(),
"reviewCount": reviewCount.toString()
}
};
---
<script type="application/ld+json" set:html={JSON.stringify(schema)} />
Validate the schema in Google Rich Results Test. If it’s green, it’s correct.
Step 4: Quality photos
Google shows clinic photos in local results. Good photos = more clicks.
Minimum:
- 1 exterior photo (facade)
- 3 interior photos (waiting room, office, chair)
- 1 team photo (dentist + assistant)
- 3 case photos (before/after anonymous)
Ideal:
- Professional photographer does a day shoot to capture everything. Costs R$ 500-1,200. Worth it.
- Buy or take 360 photos of each room (Google Lens and Matterport do this).
Rules:
- Minimum 1080px wide
- Good lighting (not dark)
- No patients with visible faces (privacy)
- Caption on each photo (room name, service)
Upload to GBP, site, and schema.org.
Step 5: Aggressive reviews
Reviews are 15-20% of local ranking. Site with 0 reviews ranks worse than site with 30.
Your job: get 30-50 5-star reviews in 3 months.
How to ask without seeming weird:
Bad: “Leave your review on Google to help me”. Good: After appointment, receptionist says “Can you do me a favor? Leave a quick comment on Google about your experience here. Takes 20 seconds”.
Tool: Google Reviews API. You can create pre-filled links so patient doesn’t have to search:
https://search.google.com/local/writereview?placeid=ChIJXXXXXXXXXX
Get your placeid on Google Maps (in browser, inspect code, search for placeId).
Automation: after first appointment, send email + SMS: “Were you happy with the experience? Leave a review: [review link]”
Resend + Zapier solves this in 30 minutes.
Reply to EVERYTHING: every review, you respond in less than 48 hours.
Positive review: “João, thank you so much for choosing us! Your smile looks amazing. See you in 6 months!”.
Negative review: “We apologize for what happened. Can you reach out privately so we can fix it? We want to improve”.
Customers who see you responding think “this clinic takes it seriously”.
Checklist table: Local SEO by item
| Tasks | GBP | NAP | Schema | Photos | Reviews |
|---|---|---|---|---|---|
| Main category | Yes | - | - | - | - |
| Secondary categories | Yes | - | - | - | - |
| 750 char description | Yes | - | - | - | - |
| Correct hours | Yes | Yes | Yes | - | - |
| Phone | Yes | Yes | Yes | - | - |
| Complete address | Yes | Yes | Yes | - | - |
| 10+ photos | Yes | - | - | Yes | - |
| Intro video | Yes | - | - | - | - |
| Posts 2x/month | Yes | - | - | - | - |
| Active offers | Yes | - | - | - | - |
| Q&A responses | Yes | - | - | - | Yes |
| 30+ reviews | - | - | - | - | Yes |
| Review responses | - | - | - | - | Yes |
| LocalBusiness schema | - | - | Yes | - | - |
| Dentist schema | - | - | Yes | - | - |
| Photos in schema | - | - | Yes | Yes | - |
| NAP in footer | - | Yes | - | - | - |
Real case: Bela Vista, 90 days
Day 1: clinic was in position 8.
Day 30:
- GBP 100% complete
- Schema on site
- 100 organized photos
- Asked for 15 reviews (got 13)
Day 60:
- Position 4 in “dentist Bela Vista”
- 35 accumulated reviews
- Started review collection automation
Day 90:
- Position 1 in “dentist Bela Vista”
- Position 2 in “implant Bela Vista”
- Position 3 in “dental cleaning Bela Vista”
- 52 accumulated reviews
Result: 18 new patients in 90 days (was 6-7 before).
Average ticket: R$ 600 (first consultation). Revenue: R$ 10,800 against zero cost (did it themselves).
Mistakes I made
I tried to add 500 bot reviews. Google detected it, hated it, dropped from position 3 to 6. Lesson: reviews have to be real.
I updated GBP only when I remembered. Review stayed incomplete for 2 months, Google hated it. Now: update 1x per week (takes 5 minutes).
I didn’t respond to negative reviews. Customers saw this and lost trust. Now: respond to EVERYTHING in less than 24 hours.
I forgot to put the Google Maps link in the site footer. NAP was only in one place. After adding it everywhere (footer, contact, header), ranking went up.
Action checklist (next 90 days)
- Audit current GBP (complete? Old photo?)
- Get professional photos of office (10-15 photos)
- Update GBP: photo, description, categories, hours, attributes
- Add 2 GBP offers
- Publish 1 post/week on GBP for 4 weeks
- Check NAP: site, GBP, Bing, Yellow Pages (equal?)
- Implement schema.org on site (JSON-LD Dentist)
- Validate schema in Google Rich Results Test
- Automate review collection (post-appointment email)
- Ask for 30 reviews from last 6 months of customers
- Respond to ALL reviews in less than 24 hours
- Set up Google Maps link in footer + contact page
Read also: Online booking for dental clinics with Astro + Supabase | WhatsApp Business API for dental clinics | Dental clinics losing patients because of their website
Conclusion
Local SEO for clinics is magic because it seems complicated, but it’s simple. Complete GBP, consistent NAP everywhere, schema on site, photos, reviews.
3 months of work takes you from position 8 to position 1. Position 1 isn’t 10% more patients. It’s 150%+ more patients. Google says 70% of clicks go to top 3.
If you’re not in positions 1, 2, 3, you’re losing money. Literally. Patient is typing your neighborhood right now, seeing your competitor in first place.
Investment is R$ 500-1k (photographer) and 20 hours of work. ROI is 10 times that in 90 days.
Start today. Audit your GBP right now. If it’s empty, fill it. If it’s old, update it. One hour per week for 3 months puts you in first place.
Your competitor is sleeping. Wake up and win.