Back to News & Insights
SEO October 12, 2026 · 7 min read

Every long-form page on our site has a required sources array, and two of them are empty

A required TypeScript field guarantees the field exists. It does not guarantee the field says anything, and the layout that hides the empty case is what made the gap invisible.

Every long-form page on our site has a required sources array, and two of them are empty

Notifio has eight long-form pages. Five are guides, under notifio.app/guides, and three are audience pages under /for/, for people who describe themselves rather than their task. Both routes render the same type, which is a decision I wrote about in Same document, two URL spaces, because intent is not content.

sources being required is doing the same job as everything else in that type, which is to make a page impossible to half-write. I used the same approach on the per-site alert pages, where the type is the entry requirement: Fifteen required fields and no optional ones, because the type decides whether a site gets a page.

A page that makes claims about how other companies' alerts work, which several of these do, is only worth reading if you can check it. So: required field.

I went and counted the arrays rather than trusting the type, which is the entire point of this post. Six of the eight pages cite something. Here is the full inventory.

sources: [] satisfies sources: ArticleSource[] perfectly. TypeScript asked whether the field exists, got a yes, and has no opinion about whether it says anything. Required is a statement about the shape of the object, and what I thought I was writing down was a statement about the content of the page.

This is not a subtle distinction once you see it, and I still wrote it, because the form of the fix looks like the form of the problem. Making a field required feels like making a rule. It makes a slot.

That guard is correct. A "Sources" heading over an empty list is worse than no heading, so the empty case renders as nothing at all.

It also means the two pages with no citations do not look like pages missing their citations. They look like pages that do not have a Sources section, which is a completely normal thing for a page to not have. The empty state being invisible in the UI is exactly what you want for readers and exactly what you do not want for yourself.

Worth noting which two they are, because it is not random. The first message to a landlord and the rental documents checklist are the two pages made out of judgement rather than out of facts about somebody else's product. There is no authority to cite for what to put in an opening message. The four-source page, how fast rental listings go, is entirely about other companies' published behaviour, so almost every sentence has somewhere to point.

Which means the rule I actually want is not "every page has a source". It is "every claim about a third party has a source", and that is not a thing a type can express. A required non-empty array would have produced a decorative citation on the two pages that do not need one, which is worse than an honest gap: a reader who clicks a source and finds it has nothing to do with the sentence above it has learned something true about how carefully the page was written.

So the useful version is narrower. The website's tests already load these exact collections, for the metadata length budget I wrote about in Our title budget is 60 characters, the layout quietly spends ten of them, and a test reads our own source files to prove it:

A page that names no company is allowed to cite nothing. A page that names one has to point somewhere. That is a crude approximation of the real rule and it fails in the right direction, and the failure message names the company, so the person who sees it in CI knows what the test is asking for rather than just that an array is empty.

I have not added it yet, which is the honest state of things. The reason this post exists is that counting the arrays was more useful than any amount of looking at the type.

noopener is the uninteresting half: target="_blank" without it gives the opened page a handle on window.opener, and modern browsers imply it now, but it costs nothing to be explicit.

nofollow is a decision, and Google's own documentation describes the case it is for:

Use the nofollow value when other values don't apply, and you'd rather Google not associate your site with, or crawl the linked page from, your site.

Look at what the sources on these pages actually are. Pararius' page about what Pararius+ includes. SpareRoom's explanation of Early Bird. Rightmove's FAQ on how Property Alerts work. Idealista's help article on email alerts. Kamernet's how-it-works page. These are competitors' own help pages, cited because for a claim about how a company's alerts behave, the company's own documentation is the primary source and anything else is hearsay.

Citing them is honest and necessary. Volunteering ranking signal to them from a page that exists partly to compete with them is a separate act, and nothing about accurate citation requires it. Google's page is also clear that nofollow is not a cloak: "the linked pages may be found through other means, such as sitemaps or links from other sites, and thus they may still be crawled." Nothing is being hidden. The link works, the reader can check the claim, and the attribute only says I am not passing an endorsement along with it.

Want to discuss this further?

Book a free strategy call with our team to see how these insights apply to your specific business goals.

Book a consultation