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; export type SeoRoute = { path: string; title: string; description: string; index: boolean; }; export const INDEXABLE_ROUTES: SeoRoute[] = routesFile.routes.map((r) => ({ ...r, index: true, })); export const NOT_FOUND_SEO: SeoRoute = { path: '', title: 'Page not found — LexAI', description: 'That address is not a LexAI page.', index: false, }; const byPath = new Map(INDEXABLE_ROUTES.map((r) => [r.path, r])); export function seoForPath(pathname: string): SeoRoute { const normalized = pathname.replace(/\/+$/, '') || '/'; return byPath.get(normalized) ?? NOT_FOUND_SEO; } 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 { 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 }; }