internal/frontend: make links on 404 => Request page clickable

If the user arrives at the 404 page and clicks the
Request <package-name> button, there are two possible
responses from fetch.go that contain links. This
makes those links clickable.

These URLs show these two locations upon clicking Request:
https://pkg.go.dev/github.com/google/go-cloud@v0.20.0
https://pkg.go.dev/github.com/hashicorp/vault/@master/api

Fixes golang/go#40306

Change-Id: I1dacc8ad3a7337a3c02079381ab454a1678cc681
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/277117
Reviewed-by: Jamal Carvalho <jamal@golang.org>
Reviewed-by: Julie Qiu <julie@golang.org>
Trust: Jamal Carvalho <jamal@golang.org>
Trust: Julie Qiu <julie@golang.org>
Run-TryBot: Julie Qiu <julie@golang.org>
diff --git a/content/static/js/fetch.js b/content/static/js/fetch.js
index b0d96eb..3a89e4b 100644
--- a/content/static/js/fetch.js
+++ b/content/static/js/fetch.js
@@ -29,5 +29,7 @@
   const responseText = await response.text();
   document.querySelector('.js-fetchLoading').style.display = 'none';
   document.querySelector('.js-fetchMessageSecondary').textContent = '';
-  document.querySelector('.js-fetchMessage').textContent = responseText;
+  const responseTextParsedDOM = new DOMParser().parseFromString(responseText, 'text/html');
+  document.querySelector('.js-fetchMessage').innerHTML =
+    responseTextParsedDOM.documentElement.textContent;
 }
diff --git a/content/static/js/fetch.min.js b/content/static/js/fetch.min.js
index 8f70514..001a669 100644
--- a/content/static/js/fetch.min.js
+++ b/content/static/js/fetch.min.js
@@ -5,36 +5,36 @@
  license that can be found in the LICENSE file.
 */
 var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.createTemplateTagFirstArg=function(a){return a.raw=a};$jscomp.createTemplateTagFirstArgWithRaw=function(a,b){a.raw=b;return a};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.SIMPLE_FROUND_POLYFILL=!1;$jscomp.ISOLATE_POLYFILLS=!1;
-$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,d){if(a==Array.prototype||a==Object.prototype)return a;a[b]=d.value;return a};$jscomp.getGlobal=function(a){a=["object"==typeof globalThis&&globalThis,a,"object"==typeof window&&window,"object"==typeof self&&self,"object"==typeof global&&global];for(var b=0;b<a.length;++b){var d=a[b];if(d&&d.Math==Math)return d}throw Error("Cannot find global object");};$jscomp.global=$jscomp.getGlobal(this);
-$jscomp.IS_SYMBOL_NATIVE="function"===typeof Symbol&&"symbol"===typeof Symbol("x");$jscomp.TRUST_ES6_POLYFILLS=!$jscomp.ISOLATE_POLYFILLS||$jscomp.IS_SYMBOL_NATIVE;$jscomp.polyfills={};$jscomp.propertyToPolyfillSymbol={};$jscomp.POLYFILL_PREFIX="$jscp$";var $jscomp$lookupPolyfilledValue=function(a,b){var d=$jscomp.propertyToPolyfillSymbol[b];if(null==d)return a[b];d=a[d];return void 0!==d?d:a[b]};
-$jscomp.polyfill=function(a,b,d,f){b&&($jscomp.ISOLATE_POLYFILLS?$jscomp.polyfillIsolated(a,b,d,f):$jscomp.polyfillUnisolated(a,b,d,f))};$jscomp.polyfillUnisolated=function(a,b,d,f){d=$jscomp.global;a=a.split(".");for(f=0;f<a.length-1;f++){var e=a[f];if(!(e in d))return;d=d[e]}a=a[a.length-1];f=d[a];b=b(f);b!=f&&null!=b&&$jscomp.defineProperty(d,a,{configurable:!0,writable:!0,value:b})};
-$jscomp.polyfillIsolated=function(a,b,d,f){var e=a.split(".");a=1===e.length;f=e[0];f=!a&&f in $jscomp.polyfills?$jscomp.polyfills:$jscomp.global;for(var l=0;l<e.length-1;l++){var c=e[l];if(!(c in f))return;f=f[c]}e=e[e.length-1];d=$jscomp.IS_SYMBOL_NATIVE&&"es6"===d?f[e]:null;b=b(d);null!=b&&(a?$jscomp.defineProperty($jscomp.polyfills,e,{configurable:!0,writable:!0,value:b}):b!==d&&($jscomp.propertyToPolyfillSymbol[e]=$jscomp.IS_SYMBOL_NATIVE?$jscomp.global.Symbol(e):$jscomp.POLYFILL_PREFIX+e,e=
-$jscomp.propertyToPolyfillSymbol[e],$jscomp.defineProperty(f,e,{configurable:!0,writable:!0,value:b})))};$jscomp.underscoreProtoCanBeSet=function(){var a={a:!0},b={};try{return b.__proto__=a,b.a}catch(d){}return!1};$jscomp.setPrototypeOf=$jscomp.TRUST_ES6_POLYFILLS&&"function"==typeof Object.setPrototypeOf?Object.setPrototypeOf:$jscomp.underscoreProtoCanBeSet()?function(a,b){a.__proto__=b;if(a.__proto__!==b)throw new TypeError(a+" is not extensible");return a}:null;
+$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,e){if(a==Array.prototype||a==Object.prototype)return a;a[b]=e.value;return a};$jscomp.getGlobal=function(a){a=["object"==typeof globalThis&&globalThis,a,"object"==typeof window&&window,"object"==typeof self&&self,"object"==typeof global&&global];for(var b=0;b<a.length;++b){var e=a[b];if(e&&e.Math==Math)return e}throw Error("Cannot find global object");};$jscomp.global=$jscomp.getGlobal(this);
+$jscomp.IS_SYMBOL_NATIVE="function"===typeof Symbol&&"symbol"===typeof Symbol("x");$jscomp.TRUST_ES6_POLYFILLS=!$jscomp.ISOLATE_POLYFILLS||$jscomp.IS_SYMBOL_NATIVE;$jscomp.polyfills={};$jscomp.propertyToPolyfillSymbol={};$jscomp.POLYFILL_PREFIX="$jscp$";var $jscomp$lookupPolyfilledValue=function(a,b){var e=$jscomp.propertyToPolyfillSymbol[b];if(null==e)return a[b];e=a[e];return void 0!==e?e:a[b]};
+$jscomp.polyfill=function(a,b,e,f){b&&($jscomp.ISOLATE_POLYFILLS?$jscomp.polyfillIsolated(a,b,e,f):$jscomp.polyfillUnisolated(a,b,e,f))};$jscomp.polyfillUnisolated=function(a,b,e,f){e=$jscomp.global;a=a.split(".");for(f=0;f<a.length-1;f++){var d=a[f];if(!(d in e))return;e=e[d]}a=a[a.length-1];f=e[a];b=b(f);b!=f&&null!=b&&$jscomp.defineProperty(e,a,{configurable:!0,writable:!0,value:b})};
+$jscomp.polyfillIsolated=function(a,b,e,f){var d=a.split(".");a=1===d.length;f=d[0];f=!a&&f in $jscomp.polyfills?$jscomp.polyfills:$jscomp.global;for(var l=0;l<d.length-1;l++){var c=d[l];if(!(c in f))return;f=f[c]}d=d[d.length-1];e=$jscomp.IS_SYMBOL_NATIVE&&"es6"===e?f[d]:null;b=b(e);null!=b&&(a?$jscomp.defineProperty($jscomp.polyfills,d,{configurable:!0,writable:!0,value:b}):b!==e&&($jscomp.propertyToPolyfillSymbol[d]=$jscomp.IS_SYMBOL_NATIVE?$jscomp.global.Symbol(d):$jscomp.POLYFILL_PREFIX+d,d=
+$jscomp.propertyToPolyfillSymbol[d],$jscomp.defineProperty(f,d,{configurable:!0,writable:!0,value:b})))};$jscomp.underscoreProtoCanBeSet=function(){var a={a:!0},b={};try{return b.__proto__=a,b.a}catch(e){}return!1};$jscomp.setPrototypeOf=$jscomp.TRUST_ES6_POLYFILLS&&"function"==typeof Object.setPrototypeOf?Object.setPrototypeOf:$jscomp.underscoreProtoCanBeSet()?function(a,b){a.__proto__=b;if(a.__proto__!==b)throw new TypeError(a+" is not extensible");return a}:null;
 $jscomp.arrayIteratorImpl=function(a){var b=0;return function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}}};$jscomp.arrayIterator=function(a){return{next:$jscomp.arrayIteratorImpl(a)}};$jscomp.makeIterator=function(a){var b="undefined"!=typeof Symbol&&Symbol.iterator&&a[Symbol.iterator];return b?b.call(a):$jscomp.arrayIterator(a)};$jscomp.generator={};
 $jscomp.generator.ensureIteratorResultIsObject_=function(a){if(!(a instanceof Object))throw new TypeError("Iterator result "+a+" is not an object");};$jscomp.generator.Context=function(){this.isRunning_=!1;this.yieldAllIterator_=null;this.yieldResult=void 0;this.nextAddress=1;this.finallyAddress_=this.catchAddress_=0;this.finallyContexts_=this.abruptCompletion_=null};
 $jscomp.generator.Context.prototype.start_=function(){if(this.isRunning_)throw new TypeError("Generator is already running");this.isRunning_=!0};$jscomp.generator.Context.prototype.stop_=function(){this.isRunning_=!1};$jscomp.generator.Context.prototype.jumpToErrorHandler_=function(){this.nextAddress=this.catchAddress_||this.finallyAddress_};$jscomp.generator.Context.prototype.next_=function(a){this.yieldResult=a};
 $jscomp.generator.Context.prototype.throw_=function(a){this.abruptCompletion_={exception:a,isException:!0};this.jumpToErrorHandler_()};$jscomp.generator.Context.prototype.return=function(a){this.abruptCompletion_={return:a};this.nextAddress=this.finallyAddress_};$jscomp.generator.Context.prototype.jumpThroughFinallyBlocks=function(a){this.abruptCompletion_={jumpTo:a};this.nextAddress=this.finallyAddress_};$jscomp.generator.Context.prototype.yield=function(a,b){this.nextAddress=b;return{value:a}};
-$jscomp.generator.Context.prototype.yieldAll=function(a,b){a=$jscomp.makeIterator(a);var d=a.next();$jscomp.generator.ensureIteratorResultIsObject_(d);if(d.done)this.yieldResult=d.value,this.nextAddress=b;else return this.yieldAllIterator_=a,this.yield(d.value,b)};$jscomp.generator.Context.prototype.jumpTo=function(a){this.nextAddress=a};$jscomp.generator.Context.prototype.jumpToEnd=function(){this.nextAddress=0};
+$jscomp.generator.Context.prototype.yieldAll=function(a,b){a=$jscomp.makeIterator(a);var e=a.next();$jscomp.generator.ensureIteratorResultIsObject_(e);if(e.done)this.yieldResult=e.value,this.nextAddress=b;else return this.yieldAllIterator_=a,this.yield(e.value,b)};$jscomp.generator.Context.prototype.jumpTo=function(a){this.nextAddress=a};$jscomp.generator.Context.prototype.jumpToEnd=function(){this.nextAddress=0};
 $jscomp.generator.Context.prototype.setCatchFinallyBlocks=function(a,b){this.catchAddress_=a;void 0!=b&&(this.finallyAddress_=b)};$jscomp.generator.Context.prototype.setFinallyBlock=function(a){this.catchAddress_=0;this.finallyAddress_=a||0};$jscomp.generator.Context.prototype.leaveTryBlock=function(a,b){this.nextAddress=a;this.catchAddress_=b||0};
-$jscomp.generator.Context.prototype.enterCatchBlock=function(a){this.catchAddress_=a||0;a=this.abruptCompletion_.exception;this.abruptCompletion_=null;return a};$jscomp.generator.Context.prototype.enterFinallyBlock=function(a,b,d){d?this.finallyContexts_[d]=this.abruptCompletion_:this.finallyContexts_=[this.abruptCompletion_];this.catchAddress_=a||0;this.finallyAddress_=b||0};
+$jscomp.generator.Context.prototype.enterCatchBlock=function(a){this.catchAddress_=a||0;a=this.abruptCompletion_.exception;this.abruptCompletion_=null;return a};$jscomp.generator.Context.prototype.enterFinallyBlock=function(a,b,e){e?this.finallyContexts_[e]=this.abruptCompletion_:this.finallyContexts_=[this.abruptCompletion_];this.catchAddress_=a||0;this.finallyAddress_=b||0};
 $jscomp.generator.Context.prototype.leaveFinallyBlock=function(a,b){b=this.finallyContexts_.splice(b||0)[0];if(b=this.abruptCompletion_=this.abruptCompletion_||b){if(b.isException)return this.jumpToErrorHandler_();void 0!=b.jumpTo&&this.finallyAddress_<b.jumpTo?(this.nextAddress=b.jumpTo,this.abruptCompletion_=null):this.nextAddress=this.finallyAddress_}else this.nextAddress=a};$jscomp.generator.Context.prototype.forIn=function(a){return new $jscomp.generator.Context.PropertyIterator(a)};
 $jscomp.generator.Context.PropertyIterator=function(a){this.object_=a;this.properties_=[];for(var b in a)this.properties_.push(b);this.properties_.reverse()};$jscomp.generator.Context.PropertyIterator.prototype.getNext=function(){for(;0<this.properties_.length;){var a=this.properties_.pop();if(a in this.object_)return a}return null};$jscomp.generator.Engine_=function(a){this.context_=new $jscomp.generator.Context;this.program_=a};
 $jscomp.generator.Engine_.prototype.next_=function(a){this.context_.start_();if(this.context_.yieldAllIterator_)return this.yieldAllStep_(this.context_.yieldAllIterator_.next,a,this.context_.next_);this.context_.next_(a);return this.nextStep_()};
-$jscomp.generator.Engine_.prototype.return_=function(a){this.context_.start_();var b=this.context_.yieldAllIterator_;if(b)return this.yieldAllStep_("return"in b?b["return"]:function(d){return{value:d,done:!0}},a,this.context_.return);this.context_.return(a);return this.nextStep_()};
+$jscomp.generator.Engine_.prototype.return_=function(a){this.context_.start_();var b=this.context_.yieldAllIterator_;if(b)return this.yieldAllStep_("return"in b?b["return"]:function(e){return{value:e,done:!0}},a,this.context_.return);this.context_.return(a);return this.nextStep_()};
 $jscomp.generator.Engine_.prototype.throw_=function(a){this.context_.start_();if(this.context_.yieldAllIterator_)return this.yieldAllStep_(this.context_.yieldAllIterator_["throw"],a,this.context_.next_);this.context_.throw_(a);return this.nextStep_()};
-$jscomp.generator.Engine_.prototype.yieldAllStep_=function(a,b,d){try{var f=a.call(this.context_.yieldAllIterator_,b);$jscomp.generator.ensureIteratorResultIsObject_(f);if(!f.done)return this.context_.stop_(),f;var e=f.value}catch(l){return this.context_.yieldAllIterator_=null,this.context_.throw_(l),this.nextStep_()}this.context_.yieldAllIterator_=null;d.call(this.context_,e);return this.nextStep_()};
+$jscomp.generator.Engine_.prototype.yieldAllStep_=function(a,b,e){try{var f=a.call(this.context_.yieldAllIterator_,b);$jscomp.generator.ensureIteratorResultIsObject_(f);if(!f.done)return this.context_.stop_(),f;var d=f.value}catch(l){return this.context_.yieldAllIterator_=null,this.context_.throw_(l),this.nextStep_()}this.context_.yieldAllIterator_=null;e.call(this.context_,d);return this.nextStep_()};
 $jscomp.generator.Engine_.prototype.nextStep_=function(){for(;this.context_.nextAddress;)try{var a=this.program_(this.context_);if(a)return this.context_.stop_(),{value:a.value,done:!1}}catch(b){this.context_.yieldResult=void 0,this.context_.throw_(b)}this.context_.stop_();if(this.context_.abruptCompletion_){a=this.context_.abruptCompletion_;this.context_.abruptCompletion_=null;if(a.isException)throw a.exception;return{value:a.return,done:!0}}return{value:void 0,done:!0}};
 $jscomp.generator.Generator_=function(a){this.next=function(b){return a.next_(b)};this.throw=function(b){return a.throw_(b)};this.return=function(b){return a.return_(b)};this[Symbol.iterator]=function(){return this}};$jscomp.generator.createGenerator=function(a,b){b=new $jscomp.generator.Generator_(new $jscomp.generator.Engine_(b));$jscomp.setPrototypeOf&&a.prototype&&$jscomp.setPrototypeOf(b,a.prototype);return b};
-$jscomp.asyncExecutePromiseGenerator=function(a){function b(f){return a.next(f)}function d(f){return a.throw(f)}return new Promise(function(f,e){function l(c){c.done?f(c.value):Promise.resolve(c.value).then(b,d).then(l,e)}l(a.next())})};$jscomp.asyncExecutePromiseGeneratorFunction=function(a){return $jscomp.asyncExecutePromiseGenerator(a())};$jscomp.asyncExecutePromiseGeneratorProgram=function(a){return $jscomp.asyncExecutePromiseGenerator(new $jscomp.generator.Generator_(new $jscomp.generator.Engine_(a)))};
-$jscomp.initSymbol=function(){};$jscomp.polyfill("Symbol",function(a){if(a)return a;var b=function(e,l){this.$jscomp$symbol$id_=e;$jscomp.defineProperty(this,"description",{configurable:!0,writable:!0,value:l})};b.prototype.toString=function(){return this.$jscomp$symbol$id_};var d=0,f=function(e){if(this instanceof f)throw new TypeError("Symbol is not a constructor");return new b("jscomp_symbol_"+(e||"")+"_"+d++,e)};return f},"es6","es3");$jscomp.initSymbolIterator=function(){};
-$jscomp.polyfill("Symbol.iterator",function(a){if(a)return a;a=Symbol("Symbol.iterator");for(var b="Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array".split(" "),d=0;d<b.length;d++){var f=$jscomp.global[b[d]];"function"===typeof f&&"function"!=typeof f.prototype[a]&&$jscomp.defineProperty(f.prototype,a,{configurable:!0,writable:!0,value:function(){return $jscomp.iteratorPrototype($jscomp.arrayIteratorImpl(this))}})}return a},"es6",
+$jscomp.asyncExecutePromiseGenerator=function(a){function b(f){return a.next(f)}function e(f){return a.throw(f)}return new Promise(function(f,d){function l(c){c.done?f(c.value):Promise.resolve(c.value).then(b,e).then(l,d)}l(a.next())})};$jscomp.asyncExecutePromiseGeneratorFunction=function(a){return $jscomp.asyncExecutePromiseGenerator(a())};$jscomp.asyncExecutePromiseGeneratorProgram=function(a){return $jscomp.asyncExecutePromiseGenerator(new $jscomp.generator.Generator_(new $jscomp.generator.Engine_(a)))};
+$jscomp.initSymbol=function(){};$jscomp.polyfill("Symbol",function(a){if(a)return a;var b=function(d,l){this.$jscomp$symbol$id_=d;$jscomp.defineProperty(this,"description",{configurable:!0,writable:!0,value:l})};b.prototype.toString=function(){return this.$jscomp$symbol$id_};var e=0,f=function(d){if(this instanceof f)throw new TypeError("Symbol is not a constructor");return new b("jscomp_symbol_"+(d||"")+"_"+e++,d)};return f},"es6","es3");$jscomp.initSymbolIterator=function(){};
+$jscomp.polyfill("Symbol.iterator",function(a){if(a)return a;a=Symbol("Symbol.iterator");for(var b="Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array".split(" "),e=0;e<b.length;e++){var f=$jscomp.global[b[e]];"function"===typeof f&&"function"!=typeof f.prototype[a]&&$jscomp.defineProperty(f.prototype,a,{configurable:!0,writable:!0,value:function(){return $jscomp.iteratorPrototype($jscomp.arrayIteratorImpl(this))}})}return a},"es6",
 "es3");$jscomp.initSymbolAsyncIterator=function(){};$jscomp.iteratorPrototype=function(a){a={next:a};a[Symbol.iterator]=function(){return this};return a};$jscomp.FORCE_POLYFILL_PROMISE=!1;
-$jscomp.polyfill("Promise",function(a){function b(){this.batch_=null}function d(c){return c instanceof e?c:new e(function(g,h){g(c)})}if(a&&!$jscomp.FORCE_POLYFILL_PROMISE)return a;b.prototype.asyncExecute=function(c){if(null==this.batch_){this.batch_=[];var g=this;this.asyncExecuteFunction(function(){g.executeBatch_()})}this.batch_.push(c)};var f=$jscomp.global.setTimeout;b.prototype.asyncExecuteFunction=function(c){f(c,0)};b.prototype.executeBatch_=function(){for(;this.batch_&&this.batch_.length;){var c=
-this.batch_;this.batch_=[];for(var g=0;g<c.length;++g){var h=c[g];c[g]=null;try{h()}catch(k){this.asyncThrow_(k)}}}this.batch_=null};b.prototype.asyncThrow_=function(c){this.asyncExecuteFunction(function(){throw c;})};var e=function(c){this.state_=0;this.result_=void 0;this.onSettledCallbacks_=[];var g=this.createResolveAndReject_();try{c(g.resolve,g.reject)}catch(h){g.reject(h)}};e.prototype.createResolveAndReject_=function(){function c(k){return function(m){h||(h=!0,k.call(g,m))}}var g=this,h=!1;
-return{resolve:c(this.resolveTo_),reject:c(this.reject_)}};e.prototype.resolveTo_=function(c){if(c===this)this.reject_(new TypeError("A Promise cannot resolve to itself"));else if(c instanceof e)this.settleSameAsPromise_(c);else{a:switch(typeof c){case "object":var g=null!=c;break a;case "function":g=!0;break a;default:g=!1}g?this.resolveToNonPromiseObj_(c):this.fulfill_(c)}};e.prototype.resolveToNonPromiseObj_=function(c){var g=void 0;try{g=c.then}catch(h){this.reject_(h);return}"function"==typeof g?
-this.settleSameAsThenable_(g,c):this.fulfill_(c)};e.prototype.reject_=function(c){this.settle_(2,c)};e.prototype.fulfill_=function(c){this.settle_(1,c)};e.prototype.settle_=function(c,g){if(0!=this.state_)throw Error("Cannot settle("+c+", "+g+"): Promise already settled in state"+this.state_);this.state_=c;this.result_=g;this.executeOnSettledCallbacks_()};e.prototype.executeOnSettledCallbacks_=function(){if(null!=this.onSettledCallbacks_){for(var c=0;c<this.onSettledCallbacks_.length;++c)l.asyncExecute(this.onSettledCallbacks_[c]);
-this.onSettledCallbacks_=null}};var l=new b;e.prototype.settleSameAsPromise_=function(c){var g=this.createResolveAndReject_();c.callWhenSettled_(g.resolve,g.reject)};e.prototype.settleSameAsThenable_=function(c,g){var h=this.createResolveAndReject_();try{c.call(g,h.resolve,h.reject)}catch(k){h.reject(k)}};e.prototype.then=function(c,g){function h(n,p){return"function"==typeof n?function(q){try{k(n(q))}catch(r){m(r)}}:p}var k,m,t=new e(function(n,p){k=n;m=p});this.callWhenSettled_(h(c,k),h(g,m));return t};
-e.prototype.catch=function(c){return this.then(void 0,c)};e.prototype.callWhenSettled_=function(c,g){function h(){switch(k.state_){case 1:c(k.result_);break;case 2:g(k.result_);break;default:throw Error("Unexpected state: "+k.state_);}}var k=this;null==this.onSettledCallbacks_?l.asyncExecute(h):this.onSettledCallbacks_.push(h)};e.resolve=d;e.reject=function(c){return new e(function(g,h){h(c)})};e.race=function(c){return new e(function(g,h){for(var k=$jscomp.makeIterator(c),m=k.next();!m.done;m=k.next())d(m.value).callWhenSettled_(g,
-h)})};e.all=function(c){var g=$jscomp.makeIterator(c),h=g.next();return h.done?d([]):new e(function(k,m){function t(q){return function(r){n[q]=r;p--;0==p&&k(n)}}var n=[],p=0;do n.push(void 0),p++,d(h.value).callWhenSettled_(t(n.length-1),m),h=g.next();while(!h.done)})};return e},"es6","es3");var fetchButton=document.querySelector(".js-fetchButton");fetchButton&&fetchButton.addEventListener("click",function(a){a.preventDefault();fetchPath()});
-function fetchPath(){var a,b,d;return $jscomp.asyncExecutePromiseGeneratorProgram(function(f){if(1==f.nextAddress)return a=document.querySelector(".js-fetchMessage"),a.textContent="Fetching "+a.dataset.path,document.querySelector(".js-fetchMessageSecondary").textContent="Feel free to navigate away and check back later, we\u2019ll keep working on it!",document.querySelector(".js-fetchButton").style.display="none",document.querySelector(".js-fetchLoading").style.display="block",f.yield(fetch("/fetch"+
-window.location.pathname,{method:"POST"}),2);if(3!=f.nextAddress)return b=f.yieldResult,b.ok?(window.location.reload(),f.return()):f.yield(b.text(),3);d=f.yieldResult;document.querySelector(".js-fetchLoading").style.display="none";document.querySelector(".js-fetchMessageSecondary").textContent="";document.querySelector(".js-fetchMessage").textContent=d;f.jumpToEnd()})};
+$jscomp.polyfill("Promise",function(a){function b(){this.batch_=null}function e(c){return c instanceof d?c:new d(function(g,h){g(c)})}if(a&&!$jscomp.FORCE_POLYFILL_PROMISE)return a;b.prototype.asyncExecute=function(c){if(null==this.batch_){this.batch_=[];var g=this;this.asyncExecuteFunction(function(){g.executeBatch_()})}this.batch_.push(c)};var f=$jscomp.global.setTimeout;b.prototype.asyncExecuteFunction=function(c){f(c,0)};b.prototype.executeBatch_=function(){for(;this.batch_&&this.batch_.length;){var c=
+this.batch_;this.batch_=[];for(var g=0;g<c.length;++g){var h=c[g];c[g]=null;try{h()}catch(k){this.asyncThrow_(k)}}}this.batch_=null};b.prototype.asyncThrow_=function(c){this.asyncExecuteFunction(function(){throw c;})};var d=function(c){this.state_=0;this.result_=void 0;this.onSettledCallbacks_=[];var g=this.createResolveAndReject_();try{c(g.resolve,g.reject)}catch(h){g.reject(h)}};d.prototype.createResolveAndReject_=function(){function c(k){return function(m){h||(h=!0,k.call(g,m))}}var g=this,h=!1;
+return{resolve:c(this.resolveTo_),reject:c(this.reject_)}};d.prototype.resolveTo_=function(c){if(c===this)this.reject_(new TypeError("A Promise cannot resolve to itself"));else if(c instanceof d)this.settleSameAsPromise_(c);else{a:switch(typeof c){case "object":var g=null!=c;break a;case "function":g=!0;break a;default:g=!1}g?this.resolveToNonPromiseObj_(c):this.fulfill_(c)}};d.prototype.resolveToNonPromiseObj_=function(c){var g=void 0;try{g=c.then}catch(h){this.reject_(h);return}"function"==typeof g?
+this.settleSameAsThenable_(g,c):this.fulfill_(c)};d.prototype.reject_=function(c){this.settle_(2,c)};d.prototype.fulfill_=function(c){this.settle_(1,c)};d.prototype.settle_=function(c,g){if(0!=this.state_)throw Error("Cannot settle("+c+", "+g+"): Promise already settled in state"+this.state_);this.state_=c;this.result_=g;this.executeOnSettledCallbacks_()};d.prototype.executeOnSettledCallbacks_=function(){if(null!=this.onSettledCallbacks_){for(var c=0;c<this.onSettledCallbacks_.length;++c)l.asyncExecute(this.onSettledCallbacks_[c]);
+this.onSettledCallbacks_=null}};var l=new b;d.prototype.settleSameAsPromise_=function(c){var g=this.createResolveAndReject_();c.callWhenSettled_(g.resolve,g.reject)};d.prototype.settleSameAsThenable_=function(c,g){var h=this.createResolveAndReject_();try{c.call(g,h.resolve,h.reject)}catch(k){h.reject(k)}};d.prototype.then=function(c,g){function h(n,p){return"function"==typeof n?function(q){try{k(n(q))}catch(r){m(r)}}:p}var k,m,t=new d(function(n,p){k=n;m=p});this.callWhenSettled_(h(c,k),h(g,m));return t};
+d.prototype.catch=function(c){return this.then(void 0,c)};d.prototype.callWhenSettled_=function(c,g){function h(){switch(k.state_){case 1:c(k.result_);break;case 2:g(k.result_);break;default:throw Error("Unexpected state: "+k.state_);}}var k=this;null==this.onSettledCallbacks_?l.asyncExecute(h):this.onSettledCallbacks_.push(h)};d.resolve=e;d.reject=function(c){return new d(function(g,h){h(c)})};d.race=function(c){return new d(function(g,h){for(var k=$jscomp.makeIterator(c),m=k.next();!m.done;m=k.next())e(m.value).callWhenSettled_(g,
+h)})};d.all=function(c){var g=$jscomp.makeIterator(c),h=g.next();return h.done?e([]):new d(function(k,m){function t(q){return function(r){n[q]=r;p--;0==p&&k(n)}}var n=[],p=0;do n.push(void 0),p++,e(h.value).callWhenSettled_(t(n.length-1),m),h=g.next();while(!h.done)})};return d},"es6","es3");var fetchButton=document.querySelector(".js-fetchButton");fetchButton&&fetchButton.addEventListener("click",function(a){a.preventDefault();fetchPath()});
+function fetchPath(){var a,b,e,f;return $jscomp.asyncExecutePromiseGeneratorProgram(function(d){if(1==d.nextAddress)return a=document.querySelector(".js-fetchMessage"),a.textContent="Fetching "+a.dataset.path,document.querySelector(".js-fetchMessageSecondary").textContent="Feel free to navigate away and check back later, we\u2019ll keep working on it!",document.querySelector(".js-fetchButton").style.display="none",document.querySelector(".js-fetchLoading").style.display="block",d.yield(fetch("/fetch"+
+window.location.pathname,{method:"POST"}),2);if(3!=d.nextAddress)return b=d.yieldResult,b.ok?(window.location.reload(),d.return()):d.yield(b.text(),3);e=d.yieldResult;document.querySelector(".js-fetchLoading").style.display="none";document.querySelector(".js-fetchMessageSecondary").textContent="";f=(new DOMParser).parseFromString(e,"text/html");document.querySelector(".js-fetchMessage").innerHTML=f.documentElement.textContent;d.jumpToEnd()})};
diff --git a/internal/frontend/fetch.go b/internal/frontend/fetch.go
index c39c849..b85415a 100644
--- a/internal/frontend/fetch.go
+++ b/internal/frontend/fetch.go
@@ -14,6 +14,7 @@
 	"sync"
 	"time"
 
+	"github.com/google/safehtml/template"
 	"go.opencensus.io/stats"
 	"go.opencensus.io/stats/view"
 	"go.opencensus.io/tag"
@@ -233,11 +234,13 @@
 		case http.StatusInternalServerError:
 			return fr.status, "Oops! Something went wrong."
 		case derrors.ToStatus(derrors.AlternativeModule):
-			// TODO(https://golang.org/issue/40306): Make the canonical module
-			// path a clickable link.
-			return http.StatusNotFound,
-				fmt.Sprintf("“%s” is not a valid package or module. Were you looking for “%s”?",
-					displayPath(fullPath, requestedVersion), fr.goModPath)
+			t := template.Must(template.New("").Parse(`{{.}}`))
+			h, err := t.ExecuteToHTML(fmt.Sprintf("%s is not a valid path. Were you looking for “<a href='https://pkg.go.dev/%s'>%s</a>”?",
+				displayPath(fullPath, requestedVersion), fr.goModPath, fr.goModPath))
+			if err != nil {
+				return http.StatusInternalServerError, err.Error()
+			}
+			return http.StatusNotFound, h.String()
 		}
 
 		// A module was found for a prefix of the path, but the path did not exist
@@ -251,13 +254,17 @@
 		}
 	}
 	if moduleMatchingPathPrefix != "" {
-		// TODO(https://golang.org/issue/40306): Make the link clickable.
-		return http.StatusNotFound,
-			fmt.Sprintf("Package “%s” could not be found, but you can view module “%s” at https://pkg.go.dev/%s.",
-				displayPath(fullPath, requestedVersion),
-				displayPath(moduleMatchingPathPrefix, requestedVersion),
-				displayPath(moduleMatchingPathPrefix, requestedVersion),
-			)
+		t := template.Must(template.New("").Parse(`{{.}}`))
+		h, err := t.ExecuteToHTML(fmt.Sprintf("Package %s could not be found, but you can view module “%s” at <a href='https://pkg.go.dev/%s'>pkg.go.dev/%s</a>.",
+			displayPath(fullPath, requestedVersion),
+			displayPath(moduleMatchingPathPrefix, requestedVersion),
+			displayPath(moduleMatchingPathPrefix, requestedVersion),
+			displayPath(moduleMatchingPathPrefix, requestedVersion),
+		))
+		if err != nil {
+			return http.StatusInternalServerError, err.Error()
+		}
+		return http.StatusNotFound, h.String()
 	}
 	p := fullPath
 	if requestedVersion != internal.LatestVersion {
diff --git a/internal/frontend/fetch_test.go b/internal/frontend/fetch_test.go
index 7f92034..3cb53ec 100644
--- a/internal/frontend/fetch_test.go
+++ b/internal/frontend/fetch_test.go
@@ -95,38 +95,42 @@
 
 func TestFetchErrors(t *testing.T) {
 	for _, test := range []struct {
-		name, modulePath, fullPath, version string
-		fetchTimeout                        time.Duration
-		want                                int
+		name, modulePath, fullPath, version, wantErrorMessage string
+		fetchTimeout                                          time.Duration
+		want                                                  int
 	}{
 		{
-			name:       "non-existent module",
-			modulePath: "github.com/nonexistent",
-			fullPath:   "github.com/nonexistent",
-			version:    internal.LatestVersion,
-			want:       http.StatusNotFound,
+			name:             "non-existent module",
+			modulePath:       "github.com/nonexistent",
+			fullPath:         "github.com/nonexistent",
+			version:          internal.LatestVersion,
+			want:             http.StatusNotFound,
+			wantErrorMessage: "\"github.com/nonexistent\" could not be found.",
 		},
 		{
-			name:       "version invalid",
-			modulePath: testModulePath,
-			fullPath:   testModulePath,
-			version:    "random-version",
-			want:       http.StatusBadRequest,
+			name:             "version invalid",
+			modulePath:       testModulePath,
+			fullPath:         testModulePath,
+			version:          "random-version",
+			want:             http.StatusBadRequest,
+			wantErrorMessage: "Bad Request",
 		},
 		{
-			name:       "module found but package does not exist",
-			modulePath: testModulePath,
-			fullPath:   "github.com/module/pkg-nonexistent",
-			version:    internal.LatestVersion,
-			want:       http.StatusNotFound,
+			name:             "module found but package does not exist",
+			modulePath:       testModulePath,
+			fullPath:         "github.com/module/pkg-nonexistent",
+			version:          internal.LatestVersion,
+			want:             http.StatusNotFound,
+			wantErrorMessage: "Package github.com/module/pkg-nonexistent could not be found, but you can view module “github.com/module” at &lt;a href=&#39;https://pkg.go.dev/github.com/module&#39;&gt;pkg.go.dev/github.com/module&lt;/a&gt;.",
 		},
 		{
-			name:         "module exists but fetch timed out",
-			modulePath:   testModulePath,
-			fullPath:     testModulePath,
-			version:      internal.LatestVersion,
-			fetchTimeout: 1 * time.Millisecond,
-			want:         http.StatusRequestTimeout,
+			name:             "module exists but fetch timed out",
+			modulePath:       testModulePath,
+			fullPath:         testModulePath,
+			version:          internal.LatestVersion,
+			fetchTimeout:     1 * time.Millisecond,
+			want:             http.StatusRequestTimeout,
+			wantErrorMessage: "We're still working on “github.com/module”. Check back in a few minutes!",
 		},
 	} {
 		t.Run(test.name, func(t *testing.T) {
@@ -138,11 +142,17 @@
 
 			s, _, teardown := newTestServer(t, testModulesForProxy)
 			defer teardown()
-			got, _ := s.fetchAndPoll(ctx, s.getDataSource(ctx), test.modulePath, test.fullPath, test.version)
+			got, err := s.fetchAndPoll(ctx, s.getDataSource(ctx), test.modulePath, test.fullPath, test.version)
+
 			if got != test.want {
 				t.Fatalf("fetchAndPoll(ctx, testDB, q, %q, %q, %q): %d; want = %d",
 					test.modulePath, test.fullPath, test.version, got, test.want)
 			}
+
+			if err != test.wantErrorMessage {
+				t.Fatalf("fetchAndPoll(ctx, testDB, q, %q, %q, %q): %d; wantErrorMessage = %s",
+					test.modulePath, test.fullPath, test.version, got, test.wantErrorMessage)
+			}
 		})
 	}
 }