dvSeoHead function
Head tags for a page.
Open Graph and Twitter carry the same three facts under different names because the consumers read different tags; a page that sets only one previews as a blank card in whichever client reads the other.
Implementation
String dvSeoHead({
required String title,
String? description,
String? siteUrl,
String? image,
String? siteName,
Map<String, String> alternates = const <String, String>{},
String? defaultAlternate,
String type = 'website',
}) {
final tags = <String>[
'<title>${_escapeText(title)}</title>',
_meta('name', 'description', description),
if (siteUrl != null && siteUrl.isNotEmpty)
'<link rel="canonical" href="${_escapeAttribute(siteUrl)}">',
// hreflang, one link per language this page exists in. Without them a
// site with /fr/pricing and /de/pricing shows a crawler three unrelated
// pages with the same content, which engines treat as duplicates rather
// than translations. Written only when there is more than one: a lone
// hreflang reads as a misconfiguration.
if (alternates.length > 1)
for (final MapEntry<String, String> alternate in alternates.entries)
'<link rel="alternate" hreflang="${_escapeAttribute(alternate.key)}" '
'href="${_escapeAttribute(alternate.value)}">',
if (alternates.length > 1 && defaultAlternate != null)
'<link rel="alternate" hreflang="x-default" '
'href="${_escapeAttribute(defaultAlternate)}">',
_meta('property', 'og:title', title),
_meta('property', 'og:description', description),
_meta('property', 'og:type', type),
_meta('property', 'og:url', siteUrl),
_meta('property', 'og:site_name', siteName),
_meta('property', 'og:image', _absolute(image, siteUrl)),
_meta('name', 'twitter:card',
image == null ? 'summary' : 'summary_large_image'),
_meta('name', 'twitter:title', title),
_meta('name', 'twitter:description', description),
_meta('name', 'twitter:image', _absolute(image, siteUrl)),
];
return tags.where((String tag) => tag.isNotEmpty).join('\n');
}