mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
fix(seo): add structured data for sitelinks and fix OG image
Replace Organization schema with WebSite schema, add SiteNavigationElement for Documentation/FAQ/GitHub/Contact/Discord. Add BreadcrumbList to FAQ and Contact pages. Remove outdated og-image.svg (source already uses PNG). Update sitemap with lastmod and changefreq.
This commit is contained in:
@@ -1,12 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="630" viewBox="0 0 1200 630">
|
|
||||||
<defs>
|
|
||||||
<linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
||||||
<stop offset="0%" style="stop-color:#f59e0b"/>
|
|
||||||
<stop offset="100%" style="stop-color:#ea580c"/>
|
|
||||||
</linearGradient>
|
|
||||||
</defs>
|
|
||||||
<rect width="1200" height="630" fill="url(#bg)"/>
|
|
||||||
<text x="600" y="280" text-anchor="middle" font-family="system-ui, -apple-system, sans-serif" font-size="72" font-weight="800" fill="white">SnapOtter</text>
|
|
||||||
<text x="600" y="350" text-anchor="middle" font-family="system-ui, -apple-system, sans-serif" font-size="28" font-weight="400" fill="rgba(255,255,255,0.85)">Self-Hosted Image Processing</text>
|
|
||||||
<text x="600" y="400" text-anchor="middle" font-family="system-ui, -apple-system, sans-serif" font-size="20" font-weight="400" fill="rgba(255,255,255,0.6)">50+ Tools · Local AI · 100% Offline · Open Source</text>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 935 B |
@@ -2,22 +2,32 @@
|
|||||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
<url>
|
<url>
|
||||||
<loc>https://snapotter.com/</loc>
|
<loc>https://snapotter.com/</loc>
|
||||||
|
<lastmod>2026-05-16</lastmod>
|
||||||
|
<changefreq>weekly</changefreq>
|
||||||
<priority>1.0</priority>
|
<priority>1.0</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://snapotter.com/faq</loc>
|
<loc>https://snapotter.com/faq</loc>
|
||||||
<priority>0.7</priority>
|
<lastmod>2026-05-16</lastmod>
|
||||||
|
<changefreq>monthly</changefreq>
|
||||||
|
<priority>0.8</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://snapotter.com/contact</loc>
|
<loc>https://snapotter.com/contact</loc>
|
||||||
|
<lastmod>2026-05-16</lastmod>
|
||||||
|
<changefreq>monthly</changefreq>
|
||||||
<priority>0.7</priority>
|
<priority>0.7</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://snapotter.com/privacy</loc>
|
<loc>https://snapotter.com/privacy</loc>
|
||||||
|
<lastmod>2026-05-16</lastmod>
|
||||||
|
<changefreq>yearly</changefreq>
|
||||||
<priority>0.3</priority>
|
<priority>0.3</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://snapotter.com/terms</loc>
|
<loc>https://snapotter.com/terms</loc>
|
||||||
|
<lastmod>2026-05-16</lastmod>
|
||||||
|
<changefreq>yearly</changefreq>
|
||||||
<priority>0.3</priority>
|
<priority>0.3</priority>
|
||||||
</url>
|
</url>
|
||||||
</urlset>
|
</urlset>
|
||||||
|
|||||||
@@ -6,8 +6,18 @@ import { useState } from "react";
|
|||||||
|
|
||||||
import { FadeIn } from "@/components/fade-in";
|
import { FadeIn } from "@/components/fade-in";
|
||||||
import { Footer } from "@/components/footer";
|
import { Footer } from "@/components/footer";
|
||||||
|
import { JsonLd } from "@/components/json-ld";
|
||||||
import { Navbar } from "@/components/navbar";
|
import { Navbar } from "@/components/navbar";
|
||||||
|
|
||||||
|
const breadcrumbJsonLd = {
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "BreadcrumbList",
|
||||||
|
itemListElement: [
|
||||||
|
{ "@type": "ListItem", position: 1, name: "Home", item: "https://snapotter.com" },
|
||||||
|
{ "@type": "ListItem", position: 2, name: "Contact", item: "https://snapotter.com/contact" },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
const benefits = [
|
const benefits = [
|
||||||
{
|
{
|
||||||
icon: Monitor,
|
icon: Monitor,
|
||||||
@@ -63,6 +73,7 @@ export default function ContactPage() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<JsonLd data={breadcrumbJsonLd} />
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<main className="pt-16">
|
<main className="pt-16">
|
||||||
<section className="px-6 py-24 md:py-32">
|
<section className="px-6 py-24 md:py-32">
|
||||||
|
|||||||
@@ -85,10 +85,20 @@ const faqJsonLd = {
|
|||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const breadcrumbJsonLd = {
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "BreadcrumbList",
|
||||||
|
itemListElement: [
|
||||||
|
{ "@type": "ListItem", position: 1, name: "Home", item: "https://snapotter.com" },
|
||||||
|
{ "@type": "ListItem", position: 2, name: "FAQ", item: "https://snapotter.com/faq" },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
export default function FaqPage() {
|
export default function FaqPage() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<JsonLd data={faqJsonLd} />
|
<JsonLd data={faqJsonLd} />
|
||||||
|
<JsonLd data={breadcrumbJsonLd} />
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<main className="pt-16">
|
<main className="pt-16">
|
||||||
<section className="px-6 py-24 md:py-32">
|
<section className="px-6 py-24 md:py-32">
|
||||||
|
|||||||
@@ -15,13 +15,27 @@ export const metadata: Metadata = {
|
|||||||
alternates: { canonical: "https://snapotter.com" },
|
alternates: { canonical: "https://snapotter.com" },
|
||||||
};
|
};
|
||||||
|
|
||||||
const organizationJsonLd = {
|
const websiteJsonLd = {
|
||||||
"@context": "https://schema.org",
|
"@context": "https://schema.org",
|
||||||
"@type": "Organization",
|
"@type": "WebSite",
|
||||||
name: "SnapOtter",
|
name: "SnapOtter",
|
||||||
url: "https://snapotter.com",
|
url: "https://snapotter.com",
|
||||||
logo: "https://snapotter.com/logo.png",
|
description:
|
||||||
sameAs: ["https://github.com/snapotter-hq/snapotter", "https://discord.gg/hr3s7HPUsr"],
|
"52 image processing tools with local AI. Runs 100% offline. No data leaves your network.",
|
||||||
|
publisher: {
|
||||||
|
"@type": "Organization",
|
||||||
|
name: "SnapOtter",
|
||||||
|
url: "https://snapotter.com",
|
||||||
|
logo: {
|
||||||
|
"@type": "ImageObject",
|
||||||
|
url: "https://snapotter.com/logo.png",
|
||||||
|
},
|
||||||
|
sameAs: [
|
||||||
|
"https://github.com/snapotter-hq/snapotter",
|
||||||
|
"https://discord.gg/hr3s7HPUsr",
|
||||||
|
"https://hub.docker.com/r/snapotter/snapotter",
|
||||||
|
],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const softwareJsonLd = {
|
const softwareJsonLd = {
|
||||||
@@ -41,15 +55,60 @@ const softwareJsonLd = {
|
|||||||
url: "https://snapotter.com",
|
url: "https://snapotter.com",
|
||||||
downloadUrl: "https://hub.docker.com/r/snapotter/snapotter",
|
downloadUrl: "https://hub.docker.com/r/snapotter/snapotter",
|
||||||
screenshot: "https://snapotter.com/og-image.png",
|
screenshot: "https://snapotter.com/og-image.png",
|
||||||
|
image: "https://snapotter.com/og-image.png",
|
||||||
featureList:
|
featureList:
|
||||||
"Image Resize, Image Crop, Image Compression, Format Conversion, Watermarking, Background Removal, Image Upscaling, OCR, Face Detection, Photo Restoration, Batch Processing, REST API, Pipeline Automation",
|
"Image Resize, Image Crop, Image Compression, Format Conversion, Watermarking, Background Removal, Image Upscaling, OCR, Face Detection, Photo Restoration, Batch Processing, REST API, Pipeline Automation",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const navigationJsonLd = {
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "ItemList",
|
||||||
|
name: "SnapOtter Site Navigation",
|
||||||
|
itemListElement: [
|
||||||
|
{
|
||||||
|
"@type": "SiteNavigationElement",
|
||||||
|
position: 1,
|
||||||
|
name: "Documentation",
|
||||||
|
description: "Installation guides, API reference, and configuration docs",
|
||||||
|
url: "https://docs.snapotter.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "SiteNavigationElement",
|
||||||
|
position: 2,
|
||||||
|
name: "FAQ",
|
||||||
|
description: "Frequently asked questions about SnapOtter",
|
||||||
|
url: "https://snapotter.com/faq",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "SiteNavigationElement",
|
||||||
|
position: 3,
|
||||||
|
name: "GitHub",
|
||||||
|
description: "Source code, issues, and discussions",
|
||||||
|
url: "https://github.com/snapotter-hq/snapotter",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "SiteNavigationElement",
|
||||||
|
position: 4,
|
||||||
|
name: "Contact",
|
||||||
|
description: "Book a demo or discuss enterprise licensing",
|
||||||
|
url: "https://snapotter.com/contact",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "SiteNavigationElement",
|
||||||
|
position: 5,
|
||||||
|
name: "Discord",
|
||||||
|
description: "Community chat and support",
|
||||||
|
url: "https://discord.gg/hr3s7HPUsr",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<JsonLd data={organizationJsonLd} />
|
<JsonLd data={websiteJsonLd} />
|
||||||
<JsonLd data={softwareJsonLd} />
|
<JsonLd data={softwareJsonLd} />
|
||||||
|
<JsonLd data={navigationJsonLd} />
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<main>
|
<main>
|
||||||
<Hero />
|
<Hero />
|
||||||
|
|||||||
Reference in New Issue
Block a user