Compare commits
6
Commits
v0.8.3
...
5a45391d91
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a45391d91 | ||
|
|
44b90cd132 | ||
|
|
03f45d4a16 | ||
|
|
8876c5328b | ||
|
|
b08d010a9a | ||
|
|
0e4b47704c |
@@ -10,9 +10,7 @@ export default defineConfig({
|
||||
compressHTML: true,
|
||||
trailingSlash: 'ignore',
|
||||
integrations: [
|
||||
sitemap({
|
||||
lastmod: new Date(),
|
||||
}),
|
||||
sitemap(),
|
||||
react(),
|
||||
],
|
||||
vite: {
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
/* /404.html 404
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 6.4 KiB |
@@ -12,6 +12,12 @@
|
||||
"sizes": "any",
|
||||
"type": "image/svg+xml",
|
||||
"purpose": "any"
|
||||
},
|
||||
{
|
||||
"src": "/apple-touch-icon.png",
|
||||
"sizes": "180x180",
|
||||
"type": "image/png",
|
||||
"purpose": "any"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -36,8 +36,13 @@ const isProd = import.meta.env.PROD;
|
||||
<link rel="canonical" href={canonicalURL} />
|
||||
<link rel="sitemap" href="/sitemap-index.xml" />
|
||||
<link rel="icon" type="image/svg+xml" href="/gridline-icon.svg" />
|
||||
<link rel="apple-touch-icon" href="/gridline-icon.svg" />
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
||||
<link rel="manifest" href="/site.webmanifest" />
|
||||
<link rel="preload" as="image" href="/og.png" />
|
||||
<link rel="preconnect" href="https://stat.ranio.xyz" crossorigin />
|
||||
<link rel="preconnect" href="https://git.ranio.xyz" />
|
||||
<link rel="dns-prefetch" href="https://stat.ranio.xyz" />
|
||||
<link rel="dns-prefetch" href="https://git.ranio.xyz" />
|
||||
|
||||
<meta property="og:title" content={title} />
|
||||
<meta property="og:description" content={description} />
|
||||
@@ -54,6 +59,7 @@ const isProd = import.meta.env.PROD;
|
||||
<meta name="twitter:title" content={title} />
|
||||
<meta name="twitter:description" content={description} />
|
||||
<meta name="twitter:image" content={ogImageURL} />
|
||||
<meta name="twitter:image:alt" content="Gridline — the open-source database GUI" />
|
||||
<meta name="twitter:site" content="@AdrianBonpin" />
|
||||
<meta name="twitter:creator" content="@AdrianBonpin" />
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
buildWebSiteJsonLd,
|
||||
buildBreadcrumbJsonLd,
|
||||
buildTitle,
|
||||
buildProductJsonLd,
|
||||
} from "./seo";
|
||||
|
||||
describe("seo builders", () => {
|
||||
@@ -70,4 +71,18 @@ describe("seo builders", () => {
|
||||
it("buildTitle appends the brand", () => {
|
||||
expect(buildTitle("PostgreSQL GUI")).toBe("PostgreSQL GUI | Gridline");
|
||||
});
|
||||
|
||||
it("buildProductJsonLd returns valid Product schema", () => {
|
||||
const ld = buildProductJsonLd({
|
||||
name: "Gridline",
|
||||
url: "https://getgridline.app/",
|
||||
description: "Open-source database GUI",
|
||||
image: "https://getgridline.app/og.png",
|
||||
offersPrice: 0,
|
||||
offersCurrency: "USD",
|
||||
});
|
||||
expect(ld["@type"]).toBe("Product");
|
||||
expect(ld.name).toBe("Gridline");
|
||||
expect((ld.offers as { price: number }).price).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -108,3 +108,26 @@ export function buildBreadcrumbJsonLd(
|
||||
export function buildTitle(primary: string, brand = "Gridline"): string {
|
||||
return `${primary} | ${brand}`;
|
||||
}
|
||||
|
||||
export function buildProductJsonLd(opts: {
|
||||
name: string;
|
||||
url: string;
|
||||
description: string;
|
||||
image: string;
|
||||
offersPrice: number;
|
||||
offersCurrency: string;
|
||||
}): JsonLd {
|
||||
return {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Product",
|
||||
name: opts.name,
|
||||
url: opts.url,
|
||||
description: opts.description,
|
||||
image: opts.image,
|
||||
offers: {
|
||||
"@type": "Offer",
|
||||
price: opts.offersPrice,
|
||||
priceCurrency: opts.offersCurrency,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import {
|
||||
buildFaqJsonLd,
|
||||
buildOrganizationJsonLd,
|
||||
buildWebSiteJsonLd,
|
||||
buildProductJsonLd,
|
||||
buildBreadcrumbJsonLd,
|
||||
} from "../lib/seo";
|
||||
import { Image } from "astro:assets";
|
||||
import HeroDbViewer from "../components/hero/HeroDbViewer";
|
||||
@@ -42,9 +44,21 @@ const jsonLd = [
|
||||
name: "Gridline",
|
||||
url: `${site}/`,
|
||||
}),
|
||||
buildProductJsonLd({
|
||||
name: "Gridline",
|
||||
url: `${site}/`,
|
||||
description:
|
||||
"The open-source database GUI for PostgreSQL, MySQL, SQLite, and Redis. No paywalls, no tab limits, fully open source.",
|
||||
image: `${site}/og.png`,
|
||||
offersPrice: 0,
|
||||
offersCurrency: "USD",
|
||||
}),
|
||||
buildBreadcrumbJsonLd([
|
||||
{ name: "Home", url: `${site}/` },
|
||||
]),
|
||||
];
|
||||
---
|
||||
<Layout title="Gridline — Open-Source Database GUI" jsonLd={jsonLd}>
|
||||
<Layout title="Gridline — Free Open-Source Database GUI" jsonLd={jsonLd}>
|
||||
<script src="/landing.js" defer></script>
|
||||
|
||||
<!-- Hero -->
|
||||
|
||||
Reference in New Issue
Block a user