Agents helping users contact you need machine-readable contact info. Phone number rendered as an image, email obfuscated via JS, address only displayed inside a Google Maps embed — agents see none of these. The user asks "what's their phone number?" and the agent says "not listed". The fix: contact info in HTML with proper schemes (tel:, mailto:), supported by Organization + ContactPoint schema.
<img src="/contact-info.png" alt="Contact us" /> <!-- Phone, email, address all rendered as pixels. Agents see nothing. -->
<span class="email-obfusc" data-1="hello" data-2="example.com"></span> <script> // Build email from data attrs at runtime </script> <!-- Agents fetching raw HTML see no email -->
<section>
<h2>Contact us</h2>
<p>Phone:
<a href="tel:+441273555012">+44 1273 555 012</a>
</p>
<p>Email:
<a href="mailto:hello@example.com">hello@example.com</a>
</p>
<address>
Acme Ceramics<br />
12 High Street<br />
Brighton BN1 1AA<br />
United Kingdom
</address>
<p>Hours: Mon-Fri 09:00-17:00, Sat 10:00-16:00</p>
</section>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "Acme Ceramics",
"url": "https://example.com",
"logo": "https://example.com/logo.png",
"address": {
"@type": "PostalAddress",
"streetAddress": "12 High Street",
"addressLocality": "Brighton",
"postalCode": "BN1 1AA",
"addressCountry": "GB"
},
"contactPoint": [
{
"@type": "ContactPoint",
"telephone": "+44-1273-555-012",
"contactType": "customer service",
"email": "hello@example.com",
"areaServed": "GB",
"availableLanguage": ["English"]
},
{
"@type": "ContactPoint",
"telephone": "+44-1273-555-013",
"contactType": "sales",
"email": "sales@example.com",
"areaServed": ["GB", "EU"],
"availableLanguage": ["English", "French"]
},
{
"@type": "ContactPoint",
"contactType": "technical support",
"url": "https://example.com/support",
"availableLanguage": ["English"]
}
],
"sameAs": [
"https://twitter.com/acmeceramics",
"https://linkedin.com/company/acmeceramics"
]
}
</script>
Use international format for tel: hrefs — agents and phone apps parse reliably:
<!-- UK number --> <a href="tel:+441273555012">+44 1273 555 012</a> <!-- US number --> <a href="tel:+12125551234">(212) 555-1234</a> <!-- Extensions --> <a href="tel:+441273555012,123">+44 1273 555 012 ext. 123</a> <!-- Comma = pause then dial extension -->
<address itemscope itemtype="https://schema.org/PostalAddress"> <span itemprop="name">Acme Ceramics</span><br /> <span itemprop="streetAddress">12 High Street</span><br /> <span itemprop="addressLocality">Brighton</span> <span itemprop="postalCode">BN1 1AA</span><br /> <span itemprop="addressCountry">United Kingdom</span> </address> <!-- Microdata works too. JSON-LD in head is preferred but inline microdata is acceptable. -->
Visible for humans, schema for agents:
<h3>Opening hours</h3>
<ul>
<li>Monday-Friday: 09:00-17:00</li>
<li>Saturday: 10:00-16:00</li>
<li>Sunday: closed</li>
</ul>
<!-- And in LocalBusiness schema -->
"openingHoursSpecification": [
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"],
"opens": "09:00",
"closes": "17:00"
},
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Saturday"],
"opens": "10:00",
"closes": "16:00"
}
]
Google Maps iframe is fine for users but invisible to agents. Add a text fallback:
<section aria-label="Find us">
<h2>Find us</h2>
<!-- Embedded map for humans -->
<iframe src="https://www.google.com/maps/embed?..."
title="Map of Acme Ceramics location"
loading="lazy"></iframe>
<!-- Address text for agents -->
<address>
Acme Ceramics, 12 High Street, Brighton BN1 1AA
</address>
<!-- Direct map link -->
<a href="https://maps.google.com/?q=12+High+Street+Brighton+BN1+1AA">
Open in Google Maps
</a>
</section>
curl -s https://example.com/contact | grep -oE 'tel:[^"]+' curl -s https://example.com/contact | grep -oE 'mailto:[^"]+' curl -s https://example.com/contact | grep -A1 "PostalAddress" # All three should produce output