feat(website): add search-intent titles, FAQ schema, and breadcrumbs
All checks were successful
CI — Website / Website — typecheck, build (pull_request) Successful in 1m2s
All checks were successful
CI — Website / Website — typecheck, build (pull_request) Successful in 1m2s
Give Google unique snippets and FAQ rich results, and keep robots/sitemap from being cached as HTML. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import faq from './faq.json';
|
||||
import routesFile from './seo.routes.json';
|
||||
import { CHROME_STORE, REPO, VSCODE_MARKETPLACE } from './links';
|
||||
|
||||
export const SITE_ORIGIN = routesFile.origin;
|
||||
|
||||
@@ -32,3 +34,53 @@ export function canonicalUrl(path: string): string {
|
||||
if (!path || path === '/') return `${SITE_ORIGIN}/`;
|
||||
return `${SITE_ORIGIN}${path.startsWith('/') ? path : `/${path}`}`;
|
||||
}
|
||||
|
||||
function softwareGraph() {
|
||||
return {
|
||||
'@type': 'SoftwareApplication',
|
||||
name: 'LexAI',
|
||||
applicationCategory: 'BrowserApplication',
|
||||
applicationSubCategory: 'Writing assistance',
|
||||
operatingSystem: 'Chrome, VS Code, Windows, macOS, Linux',
|
||||
url: `${SITE_ORIGIN}/`,
|
||||
downloadUrl: [CHROME_STORE, VSCODE_MARKETPLACE],
|
||||
license: `${REPO}/src/branch/main/LICENSE`,
|
||||
sameAs: [REPO, CHROME_STORE, VSCODE_MARKETPLACE],
|
||||
offers: { '@type': 'Offer', price: '0', priceCurrency: 'USD' },
|
||||
};
|
||||
}
|
||||
|
||||
export function jsonLdForPath(pathname: string): Record<string, unknown> {
|
||||
const seo = seoForPath(pathname);
|
||||
const url = seo.index ? canonicalUrl(seo.path) : `${SITE_ORIGIN}${pathname}`;
|
||||
const graph: unknown[] = [
|
||||
{
|
||||
'@type': 'WebSite',
|
||||
name: 'LexAI',
|
||||
url: `${SITE_ORIGIN}/`,
|
||||
description: seoForPath('/').description,
|
||||
},
|
||||
softwareGraph(),
|
||||
];
|
||||
|
||||
if (seo.path === '/') {
|
||||
graph.push({
|
||||
'@type': 'FAQPage',
|
||||
mainEntity: faq.map((item) => ({
|
||||
'@type': 'Question',
|
||||
name: item.q,
|
||||
acceptedAnswer: { '@type': 'Answer', text: item.a },
|
||||
})),
|
||||
});
|
||||
} else if (seo.index) {
|
||||
graph.push({
|
||||
'@type': 'BreadcrumbList',
|
||||
itemListElement: [
|
||||
{ '@type': 'ListItem', position: 1, name: 'Home', item: `${SITE_ORIGIN}/` },
|
||||
{ '@type': 'ListItem', position: 2, name: seo.title, item: url },
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
return { '@context': 'https://schema.org', '@graph': graph };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user