SEO improvements
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m0s
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m0s
This commit is contained in:
@@ -584,6 +584,23 @@ async def reload_data(
|
||||
return {"status": "reloaded"}
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# SEO FILES
|
||||
# =============================================================================
|
||||
|
||||
|
||||
@app.get("/robots.txt")
|
||||
async def robots_txt():
|
||||
"""Serve robots.txt for search engine crawlers."""
|
||||
return FileResponse(settings.frontend_dir / "robots.txt", media_type="text/plain")
|
||||
|
||||
|
||||
@app.get("/sitemap.xml")
|
||||
async def sitemap_xml():
|
||||
"""Serve sitemap.xml for search engine indexing."""
|
||||
return FileResponse(settings.frontend_dir / "sitemap.xml", media_type="application/xml")
|
||||
|
||||
|
||||
# Mount static files directly (must be after all routes to avoid catching API calls)
|
||||
if settings.frontend_dir.exists():
|
||||
app.mount("/static", StaticFiles(directory=settings.frontend_dir), name="static")
|
||||
|
||||
@@ -208,6 +208,12 @@ const routes = {
|
||||
"/rankings": "rankings",
|
||||
};
|
||||
|
||||
const pageTitles = {
|
||||
dashboard: "SchoolCompare | Compare Primary School Performance",
|
||||
compare: "Compare Schools | SchoolCompare",
|
||||
rankings: "School Rankings | SchoolCompare",
|
||||
};
|
||||
|
||||
function navigateTo(path) {
|
||||
// Update URL without reload
|
||||
window.history.pushState({}, "", path);
|
||||
@@ -218,6 +224,9 @@ function handleRoute() {
|
||||
const path = window.location.pathname;
|
||||
const view = routes[path] || "dashboard";
|
||||
|
||||
// Update page title for SEO
|
||||
document.title = pageTitles[view] || pageTitles.dashboard;
|
||||
|
||||
// Update navigation
|
||||
document.querySelectorAll(".nav-link").forEach((link) => {
|
||||
link.classList.toggle("active", link.dataset.view === view);
|
||||
|
||||
@@ -4,6 +4,52 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>SchoolCompare | Compare Primary School Performance</title>
|
||||
|
||||
<!-- Primary Meta Tags -->
|
||||
<meta name="description" content="Compare primary school KS2 performance across England. Search, filter and compare Reading, Writing and Maths results for thousands of schools.">
|
||||
<meta name="keywords" content="school comparison, KS2 results, primary school performance, England schools, SATs results">
|
||||
<meta name="author" content="SchoolCompare">
|
||||
<meta name="robots" content="index, follow">
|
||||
|
||||
<!-- Canonical -->
|
||||
<link rel="canonical" href="https://schoolcompare.co.uk/">
|
||||
|
||||
<!-- Open Graph / Facebook -->
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:url" content="https://schoolcompare.co.uk/">
|
||||
<meta property="og:title" content="SchoolCompare | Compare Primary School Performance">
|
||||
<meta property="og:description" content="Compare primary school KS2 performance across England. Search and compare Reading, Writing and Maths results.">
|
||||
<meta property="og:site_name" content="SchoolCompare">
|
||||
|
||||
<!-- Twitter -->
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="twitter:url" content="https://schoolcompare.co.uk/">
|
||||
<meta name="twitter:title" content="SchoolCompare | Compare Primary School Performance">
|
||||
<meta name="twitter:description" content="Compare primary school KS2 performance across England.">
|
||||
|
||||
<!-- JSON-LD Structured Data -->
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "WebApplication",
|
||||
"name": "SchoolCompare",
|
||||
"url": "https://schoolcompare.co.uk",
|
||||
"description": "Compare primary school KS2 performance across England",
|
||||
"applicationCategory": "EducationalApplication",
|
||||
"operatingSystem": "Web",
|
||||
"offers": {
|
||||
"@type": "Offer",
|
||||
"price": "0",
|
||||
"priceCurrency": "GBP"
|
||||
},
|
||||
"author": {
|
||||
"@type": "Organization",
|
||||
"name": "SchoolCompare",
|
||||
"url": "https://schoolcompare.co.uk"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<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=DM+Sans:ital,opsz,wght@0,9..40,400;0,9..40,500;0,9..40,600;0,9..40,700&family=Playfair+Display:wght@600;700&display=swap" rel="stylesheet">
|
||||
|
||||
8
frontend/robots.txt
Normal file
8
frontend/robots.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
Allow: /compare
|
||||
Allow: /rankings
|
||||
|
||||
Disallow: /api/
|
||||
|
||||
Sitemap: https://schoolcompare.co.uk/sitemap.xml
|
||||
18
frontend/sitemap.xml
Normal file
18
frontend/sitemap.xml
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<url>
|
||||
<loc>https://schoolcompare.co.uk/</loc>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>1.0</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://schoolcompare.co.uk/compare</loc>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://schoolcompare.co.uk/rankings</loc>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
</urlset>
|
||||
Reference in New Issue
Block a user