Skip to content

Commit cd22c97

Browse files
committed
Improve 404 Google search UX
1 parent 804da13 commit cd22c97

File tree

1 file changed

+63
-13
lines changed

1 file changed

+63
-13
lines changed

404.md

Lines changed: 63 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,78 @@ things you can do from here:
1212

1313
{% assign random = site.time | date: "%s%N" | modulo: site.posts.size %}
1414

15+
<style>
16+
.c-input-text--404 {
17+
width: 100%;
18+
}
19+
20+
.c-404-search {
21+
margin-bottom: 24px;
22+
}
23+
</style>
24+
25+
<form action="https://www.google.com/search" method="get" class="c-404-search" id="js404Search">
26+
<p>
27+
<label for="js404SearchTerms">Can’t find what you’re looking for? Search CSS Wizardry with Google.</label>
28+
<input type="text" class="c-input-text c-input-text--404" id="js404SearchTerms" name="q" placeholder="your search terms" autocomplete="off" autofocus>
29+
<input type="hidden" name="as_sitesearch" value="csswizardry.com">
30+
</p>
31+
32+
<p>
33+
<input type="submit" value="Search CSS Wizardry via Google" class="btn">
34+
</p>
35+
</form>
36+
1537
1. [Head back to the home page](/)
16-
2. [Search Google for what you were looking for](https://www.google.com/search?q=site%3Acsswizardry.com+YOUR+SEARCH+TERM)
17-
3. [Browse the blog](/blog/)
18-
4. Read [<cite>{{ site.posts[random].title }}</cite>]({{ site.posts[random].url }}) <small>({{ site.posts[random].date | date: "%Y" }})</small>
38+
2. [Browse the blog](/blog/)
39+
3. Read [<cite>{{ site.posts[random].title }}</cite>]({{ site.posts[random].url }}) <small>({{ site.posts[random].date | date: "%Y" }})</small>
1940

2041
<script>
2142
(() => {
2243

23-
// Let’s try guess what they might have been looking for…
44+
const termsInput = document.getElementById('js404SearchTerms');
45+
46+
if (!termsInput) return;
47+
48+
const safeDecode = (value) => {
49+
try {
50+
return decodeURIComponent(value);
51+
} catch (_) {
52+
return value;
53+
}
54+
};
55+
56+
const normalisePathname = (pathname) => {
57+
const segments = pathname
58+
.split('/')
59+
.filter(Boolean)
60+
.map(safeDecode)
61+
.map((segment) => segment.replace(/\.[a-z0-9]+$/i, ''));
62+
63+
if (
64+
segments.length >= 2 &&
65+
/^(?:19|20)\d{2}$/.test(segments[0]) &&
66+
/^(?:0?[1-9]|1[0-2])$/.test(segments[1])
67+
) {
68+
segments.splice(0, 2);
2469

25-
// Get the current URL
26-
const url = new URL(window.location.href);
70+
if (segments[0] && /^(?:0?[1-9]|[12]\d|3[01])$/.test(segments[0])) {
71+
segments.shift();
72+
}
73+
}
2774

28-
// Grab the 404ing path
29-
const pathname = url.pathname;
75+
return segments
76+
.join(' ')
77+
.replace(/[%+]/g, ' ')
78+
.replace(/[-_]+/g, ' ')
79+
.replace(/\s+/g, ' ')
80+
.trim();
81+
};
3082

31-
// Replace any URL-like characters with spaces
32-
const formattedPath = pathname.replace(/[-_\/]+/g, ' ').trim();
83+
// Ignore query strings entirely: on this site they don’t change the content.
84+
const guessedTerms = normalisePathname(window.location.pathname);
3385

34-
// Rewrite the Google link above
35-
const anchor = document.querySelector('a[href*="google"]');
36-
anchor.href = `https://www.google.com/search?q=site%3A${url.hostname}+${encodeURIComponent(formattedPath)}`;
86+
termsInput.value = guessedTerms;
3787

3888
})();
3989
</script>

0 commit comments

Comments
 (0)