Back to Ideas 7 min read

Fifty Posts and an Empty robots.txt

E
EkoHacks Team
·

It started with a question in passing. Do we have analytics on the site? We did not know, which is an answer of its own. So we went and looked, and the looking turned into an audit, and the audit turned into this series.

Here is what a crawler found when it visited ekohacks.com on the twenty first of August, and what Google said the morning after.

One byte

public/robots.txt is one byte long. It contains a newline. Nothing forbids a crawler, nothing invites one, and nothing points at a sitemap, because there is no sitemap. /sitemap.xml returns 404.

We asked the site for sixty two routes: the pages, the legal documents, and every post in the Ideas feed. Not one of them carries an og:image, so a link to any of them shared in a chat or on a social network shows as a bare rectangle of text. Not one carries a canonical URL. Forty seven of the sixty two have a description longer than 160 characters, the median is 213 and the longest is 414, which means a search engine cuts nearly every one of them off mid sentence.

There is no analytics script. None. Our privacy policy says so, in a sentence we wrote with some pride: we do not use cookies, analytics tools, tracking pixels, or any automated data collection technologies. It is true, and it means we have no idea whether anyone has read any of the fifty posts in the repository.

The home page loads four font families from a remote provider, 241 kilobytes of type, while two more families sit in the repository as local files that nothing references. The largest element on the home page takes four and a half seconds to appear. On the Dojos page it takes almost nine.

Bing has been told the site exists, there is a verification file from July. Google had not been, until that evening.

What Google said

This section was added on the twenty second of August, the morning after this post went live. Search Console was verified on the evening of the twenty first, and we pulled the numbers through its API rather than read them off a dashboard, so that the same script can pull them again at the end of the series and nobody has to trust a screenshot.

In the twenty eight days to the twentieth of August, Google showed the site 174 times and six people clicked. All six landed on the home page. The average position was 21, which is the third page of results. Every query that surfaced us was a misspelling of the name or a near miss for something else: "eco hacks", "enviro hacking", "okhack". Not one query named a thing we write about.

Over the whole history Google holds, fifteen months, the home page took 91 clicks. The fifty posts in the Ideas feed took none. Not one click from a search engine, ever, on a post.

Then we asked about coverage, one route at a time. Of the sixty two routes, Google has 26 in its index. The other 36 it has never visited. They carry no crawl date, because nothing ever told Google they exist. Among the unvisited are every landing page except the home page: the story, the dojos, the services, the Ideas listing itself, the contact page, the curriculum, and the privacy policy.

And the routes Google does hold, it mostly holds twice. On the live site every address except the home page answers with a redirect to a twin that ends in a slash: /story sends you to /story/, and /blog/never-break-the-build to /blog/never-break-the-build/. The build writes each page as an index.html inside a folder, and the host prefers the folder's address. Every internal link on the site uses the form without the slash. So every click inside the site is a redirect hop, Google has two addresses for eighteen of the pages it kept, and no page tells it which one is real. We had not noticed, because our own audit ran against the development server, which does not redirect. The live site does.

That is day zero. Six clicks, twenty six of sixty two pages indexed, and two addresses for most of them.

The score was 100

Here is the part that made us want to write this down. We ran Lighthouse on five pages. Its SEO score was 100 on every one of them.

That is not a contradiction, it is a definition. Lighthouse checks the page it is given: is there a title, a description, is the text readable, are links crawlable, is the viewport set. Every page passes, because every page is well formed. What the score cannot see is everything that makes a page findable: whether a list of pages exists for a crawler to read, whether the page has ever been submitted anywhere, what the link looks like in the place a reader first meets it, and whether anyone has arrived. A perfect score on a page nobody can reach is a perfect score on a locked door. Six clicks and a score of 100 are the same fact seen from two sides.

This is the reframe the series rests on. Discoverability is not a marketing task that happens after the build. It is an output of the build, in the same way a passing test is. The list of pages that exist, the map that describes them, the image and description that travel with each link, the structured data that says what a page is: all of it can be produced by the same process that produces the HTML, and checked by the same process that checks the code. Where it is hand maintained, it drifts. Where it is absent, a good score hides the absence.

We know this because we have already met it once. Our blog and legal pages come from a content database that does not exist in production at request time, so any page the build did not prerender simply was not there. We fixed it by enumerating the content files at build time. That story is the next post. The post after it is about the twin addresses, which, it turns out, the same fix created. Only then does the enumeration go on to feed the sitemap, because a map has to list one address per page, and today we have two.

What we will not claim

We are not going to tell you this site became the best at anything. We cannot measure that and you could not check it. What we can do is write down the numbers on day zero, which this post has just done, make one change at a time, and write down the numbers again at the end. What moved is what we will report, and what did not move will be in the same paragraph.

The rules

Each post in the series covers one action that has shipped. The change is the evidence, and we will show the diff or the configuration rather than describe it. Every post ends with something we measured. Nothing is written before it ships, and the date on each post is the date the change went live. If you read our commit history on the working branch, it reads like this series: the change, then the post about the change.

What follows

The first half is about being findable. A page that only existed when someone linked to it, and the twin address that fix gave every page but one. One address per page, declared as canonical, before anything else is built on top. A sitemap and robots file drawn by the build from the same list that drives prerendering. The image and title that travel with a link. Structured data, and a test that fails the build when a page is missing any of it. Then the smaller things a crawler notices: fonts, the 404 page, old addresses that still need to land somewhere.

The second half is about seeing who comes, and what that costs the reader. We made a promise in our privacy policy and we meant it. We are going to reopen it, in public, and explain what we chose, what we refused to collect, and why the analytics script and the policy change land in the same commit. Then we will publish an inventory of every system that holds anything about a visitor, from the contact form to the newsletter to the payment provider, with what each one holds and for how long. And because our legal pages are markdown in the same repository as the site, we will make them show their own history, so that a policy change is something you can diff.

The last post is the measurement.

What we hold about you today

For the record, as of this post. If you fill in the contact form or sign up for the newsletter, we hold what you typed. If you book a seat at a dojo, our payment provider holds what a payment requires. Nothing else. No script on this site reports your visit to anyone, including us.

That will change at post seven. When it does, you will be able to read exactly how, in the commit and in the policy, on the same day.

E

Written by

EkoHacks Team

More from Ideas

·6 min read

What the Nullable Gave Back

One file, seven behaviours held fixed, the database swapped for a Nullable: about 180 times less time inside the tests, and coverage flat to two decimals.

E
EkoHacks Team
·6 min read

Twenty Six More Tests, Four Fewer Behaviours

Removing the mocks grew the suite from 44 tests to 70 and quietly deleted four behaviours, every one of them a failure path. Test count is not coverage.

E
EkoHacks Team
·6 min read

The Best Coverage Number in the Room

Same commit, same spec, same test count. The mocked suite ran 5.6 times faster, covered 3.5 fewer points of real code, and posted the best branch coverage.

E
EkoHacks Team