|
| 1 | +import { breadcrumbs } from './breadcrumbs.mjs'; |
| 2 | + |
| 3 | +export function structuredData({ origin, route, title, description, image, datePublished, overview = false }) { |
| 4 | + const url = new URL(route, origin).href; |
| 5 | + const home = new URL('/', origin).href; |
| 6 | + const publisher = { |
| 7 | + '@type': 'Organization', '@id': 'https://htmlcsstoimage.com/#organization', |
| 8 | + name: 'HTML/CSS to Image API', alternateName: 'HCTI', url: 'https://htmlcsstoimage.com/', |
| 9 | + description: 'Capture website screenshots, render HTML/CSS, or create templated graphics. Use MCP with AI, no-code automation, or the REST API. No browsers needed.', |
| 10 | + logo: { '@type': 'ImageObject', url: 'https://htmlcsstoimage.com/images/logo_with_black_bg.png', width: 1024, height: 1024 }, |
| 11 | + sameAs: ['https://twitter.com/htmlcsstoimage', 'https://github.com/htmlcsstoimage', 'https://www.linkedin.com/company/html-css-to-image/'], |
| 12 | + contactPoint: { '@type': 'ContactPoint', contactType: 'customer support', email: 'support@htmlcsstoimage.com' }, |
| 13 | + }; |
| 14 | + const website = { |
| 15 | + '@type': 'WebSite', '@id': `${home}#website`, url: home, |
| 16 | + name: 'HTML/CSS to Image API Docs', inLanguage: 'en', publisher: { '@id': publisher['@id'] }, |
| 17 | + }; |
| 18 | + const crumbs = breadcrumbs(route, title, Boolean(datePublished)); |
| 19 | + const breadcrumb = crumbs.length ? { |
| 20 | + '@type': 'BreadcrumbList', '@id': `${url}#breadcrumbs`, |
| 21 | + itemListElement: crumbs.map((crumb, index) => ({ |
| 22 | + '@type': 'ListItem', position: index + 1, name: crumb.label, item: new URL(crumb.link, origin).href, |
| 23 | + })), |
| 24 | + } : undefined; |
| 25 | + const page = { |
| 26 | + '@type': overview ? 'CollectionPage' : 'WebPage', '@id': `${url}#webpage`, url, |
| 27 | + name: title, description, inLanguage: 'en', isPartOf: { '@id': website['@id'] }, |
| 28 | + ...(breadcrumb ? { breadcrumb: { '@id': breadcrumb['@id'] } } : {}), |
| 29 | + ...(image ? { primaryImageOfPage: { '@type': 'ImageObject', url: image, width: 1200, height: 630 } } : {}), |
| 30 | + }; |
| 31 | + const article = overview ? undefined : { |
| 32 | + '@type': datePublished ? 'BlogPosting' : 'TechArticle', '@id': `${url}#article`, url, |
| 33 | + headline: title, description, inLanguage: 'en', mainEntityOfPage: { '@id': page['@id'] }, |
| 34 | + publisher: { '@id': publisher['@id'] }, |
| 35 | + ...(image ? { image } : {}), ...(datePublished ? { datePublished } : {}), |
| 36 | + }; |
| 37 | + return { '@context': 'https://schema.org', '@graph': [publisher, website, page, breadcrumb, article].filter(Boolean) }; |
| 38 | +} |
| 39 | + |
| 40 | +// JSON-LD is embedded in a script element, so content must not close that element. |
| 41 | +export const serializeStructuredData = data => JSON.stringify(data).replace(/</g, '\\u003c'); |
0 commit comments