SEO + UX: schema.org JSON-LD, sitemap fix, persistent topbar, POST-only rate limit
- Add schema.org JSON-LD to page, service, and location templates (LocalBusiness / Service / FAQPage) - Inject schema_json via _header.php <script type="application/ld+json"> block - Fix sitemap.xml: replace 10 stale .html refs with trailing-slash URLs, add /blog/, update lastmod - nginx: rate-limit /contact/ POST-only via map $request_method (GET no longer hits 429) - Topbar: remove dismiss button, always visible for session; popup close no longer hides topbar Verified: all 17 routes 200, JSON-LD present on home/service/location/contact, sitemap 17 URLs no .html Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ while ($row = $nav_result->fetchArray(SQLITE3_ASSOC)) {
|
||||
}
|
||||
$db->close();
|
||||
$canonical = $canonical ?? '';
|
||||
$schema_json = $schema_json ?? '';
|
||||
$page_title = htmlspecialchars($page_title ?? 'Floor It Hardwood Floors', ENT_QUOTES);
|
||||
$page_meta = htmlspecialchars($page_meta ?? '', ENT_QUOTES);
|
||||
?><!DOCTYPE html>
|
||||
@@ -21,6 +22,8 @@ $page_meta = htmlspecialchars($page_meta ?? '', ENT_QUOTES);
|
||||
<meta name="description" content="<?= $page_meta ?>">
|
||||
<?php if ($canonical): ?><link rel="canonical" href="<?= htmlspecialchars($canonical, ENT_QUOTES) ?>">
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($schema_json)): ?><script type="application/ld+json"><?= $schema_json ?></script>
|
||||
<?php endif; ?>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
@@ -32,7 +35,6 @@ $page_meta = htmlspecialchars($page_meta ?? '', ENT_QUOTES);
|
||||
<div id="promo-topbar" role="complementary" aria-label="Summer promotion">
|
||||
<span id="promo-topbar-text">Summer Refinishing Savings: Save up to 15% through June 30, 2026</span>
|
||||
<button id="promo-topbar-btn" type="button">Get Offer</button>
|
||||
<button id="promo-topbar-close" type="button" aria-label="Dismiss promotion">×</button>
|
||||
</div>
|
||||
<header id="site-header" class="site-header">
|
||||
<div class="container">
|
||||
|
||||
@@ -22,6 +22,25 @@ $body = json_decode($loc['body_json'] ?? '{}', true) ?? [];
|
||||
$faqs = json_decode($loc['faqs_json'] ?? '[]', true) ?? [];
|
||||
$city = $loc['city'];
|
||||
|
||||
$schema_json = json_encode([
|
||||
'@context' => 'https://schema.org',
|
||||
'@type' => 'HomeAndConstructionBusiness',
|
||||
'name' => 'Floor It Hardwood Floors',
|
||||
'url' => 'https://floorithardwoodfloors.com',
|
||||
'telephone'=> '+17166021429',
|
||||
'address' => [
|
||||
'@type' => 'PostalAddress',
|
||||
'addressLocality' => $loc['city'],
|
||||
'addressRegion' => 'NY',
|
||||
'addressCountry' => 'US',
|
||||
],
|
||||
'areaServed' => [
|
||||
'@type' => 'City',
|
||||
'name' => $loc['city'],
|
||||
],
|
||||
'description' => $loc['meta_description'],
|
||||
], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||
|
||||
require __DIR__ . '/../components/_header.php';
|
||||
?>
|
||||
|
||||
|
||||
@@ -20,6 +20,22 @@ $page_title = $page['title'];
|
||||
$page_meta = $page['meta_description'];
|
||||
$sections = json_decode($page['sections_json'], true) ?? [];
|
||||
|
||||
$schema_json = json_encode([
|
||||
'@context' => 'https://schema.org',
|
||||
'@type' => 'HomeAndConstructionBusiness',
|
||||
'name' => 'Floor It Hardwood Floors',
|
||||
'url' => 'https://floorithardwoodfloors.com',
|
||||
'telephone'=> '+17166021429',
|
||||
'address' => [
|
||||
'@type' => 'PostalAddress',
|
||||
'addressLocality' => 'Buffalo',
|
||||
'addressRegion' => 'NY',
|
||||
'addressCountry' => 'US',
|
||||
],
|
||||
'areaServed' => ['Buffalo','Amherst','Williamsville','Clarence','East Amherst','Lancaster'],
|
||||
'description' => $page['meta_description'],
|
||||
], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||
|
||||
require __DIR__ . '/../components/_header.php';
|
||||
|
||||
foreach ($sections as $s) {
|
||||
|
||||
@@ -21,6 +21,31 @@ $page_meta = $svc['meta_description'];
|
||||
$body = json_decode($svc['body_json'] ?? '{}', true) ?? [];
|
||||
$faqs = json_decode($svc['faqs_json'] ?? '[]', true) ?? [];
|
||||
|
||||
$schema_arr = [
|
||||
'@context' => 'https://schema.org',
|
||||
'@type' => 'Service',
|
||||
'name' => $svc['title'],
|
||||
'description' => $svc['meta_description'],
|
||||
'provider' => [
|
||||
'@type' => 'HomeAndConstructionBusiness',
|
||||
'name' => 'Floor It Hardwood Floors',
|
||||
'url' => 'https://floorithardwoodfloors.com',
|
||||
'telephone'=> '+17166021429',
|
||||
],
|
||||
'areaServed' => 'Buffalo, NY',
|
||||
];
|
||||
if (!empty($faqs)) {
|
||||
$schema_arr['@graph'] = [[
|
||||
'@type' => 'FAQPage',
|
||||
'mainEntity' => array_map(fn($f) => [
|
||||
'@type' => 'Question',
|
||||
'name' => $f['q'],
|
||||
'acceptedAnswer' => ['@type' => 'Answer', 'text' => $f['a']],
|
||||
], $faqs),
|
||||
]];
|
||||
}
|
||||
$schema_json = json_encode($schema_arr, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||
|
||||
require __DIR__ . '/../components/_header.php';
|
||||
?>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user