dvSeoApply function

String dvSeoApply(
  1. String html,
  2. String head
)

Put head into html, replacing anything already there.

The scaffolded <title> and <meta name="description"> are removed rather than left beside the generated ones, because two of either is not additive.

Implementation

String dvSeoApply(String html, String head) {
  final headEnd = html.indexOf('</head>');
  // No head to put it in. Returning the page unchanged beats inventing
  // structure around someone's template.
  if (headEnd < 0) return html;

  // The trailing newline goes with the block. Leaving it behind means each
  // rebuild adds one, which is invisible in a diff of one build and obvious
  // after twenty.
  var out = html.replaceAll(
      RegExp('$_open.*?$_close\n?', dotAll: true, multiLine: true), '');
  out = out.replaceAll(RegExp(r'<title>.*?</title>', dotAll: true), '');
  out = out.replaceAll(
      RegExp(r'''<meta\s+name=["']description["'][^>]*>''', caseSensitive: false),
      '');

  // Before the block rather than after it, and that ordering is load-bearing
  // for idempotence: inserting the viewport last would put it after the SEO
  // block on a first pass and before it on a second, so two applies would not
  // produce the same page. A build often runs over the previous build's
  // output.
  //
  // Every path that writes a built page -- the web build, the web server, the
  // static per-route pages -- goes through here, so this is the one place a
  // viewport cannot be forgotten. Left as a separate call at each of those
  // three sites it is one new code path away from being missing again, and
  // when it is missing the failure is silent: the page is perfect in a
  // desktop browser.
  out = dvViewportApply(out);

  final at = out.indexOf('</head>');
  if (at < 0) return html;
  return '${out.substring(0, at)}$_open\n$head\n$_close\n${out.substring(at)}';
}