For twelve days I have been submitting a small Chrome extension to software directories and counting the ones that publish. The count reached 58 live pages, and I was pleased with it, and the number was answering the wrong question.
A listing is not a listing. What a directory actually gives you is a link, and links are not equal. So I wrote a script that loads every one of our listing pages in a fresh anonymous browser context, finds the outbound links, and reads the rel attribute exactly as it appears in the page.
Here is what twelve days of directory submissions bought.
The numbers
24 listing pages, across 21 distinct domains.
| What the page gives | Pages | Domains |
|---|---|---|
| A followed link | 5 | 5 |
of which, on a page marked noindex
|
1 | 1 |
A link with nofollow
|
12 | 12 |
| A link to the app store instead of to us | 2 | 2 |
| Our name, and no link I could find | 5 | 3 |
One of those last five turned out not to be a directory decision at all. See the last section.
The five that give a followed link, and they are close to the entire return: make.rs, peerpush.net, startupranking.com, superlaunchlist.com, webstoreextensions.com.
That is the whole return. Not 58 pages. Five links, and one of those five is worth less than it looks, which I only found by checking one more thing.
The check I nearly did not do
Having sorted the links by rel, I almost stopped. The remaining question took one line of code: what does each page say in its robots meta tag?
Four of the five followed links sit on ordinary indexable pages. The fifth sits on a page serving noindex, follow, canonical to itself. The directory is telling search engines not to index the page at all.
A noindex, follow page does pass link signals at first. But a page that stays unindexed stops being crawled as often, and the links on it are eventually treated as if they were not there. So that row is a followed link on a page the search engine has been asked to forget.
I would not have found it by looking at rel, because rel was clean. The two attributes answer different questions and I had only been asking one of them. Four indexable followed links is the honest number.
The three things I first counted as the same
My first version of the script asked one question, does this page link to our domain, and sorted everything else into a bin called no link. That bin turned out to contain three completely different situations, and I only found out by opening two of the pages by hand.
A page can be entirely about you and link nowhere. At least, that is what I wrote here first, and the example I chose turned out to be wrong. I will come back to it, because the way it broke is the most useful thing in this post.
A page can link to the app store instead of to you. Two directories send visitors to the Chrome Web Store, with nofollow, and never mention our own domain. The traffic may still convert, and I am not complaining about it. But the authority goes to Google, not to us, and calling that a backlink is self deception.
And a page can not mention you at all any more. Worth checking, because listings do get edited.
My first script called all three of those the same thing. The distinction is the entire finding.
The example I built a section around, and how it broke
The listing I used to illustrate entirely about you, linking nowhere was ours on AlternativeTo. It runs to 896 words and names the product eighteen times. I loaded it anonymously, twice, counted 730 links on the page, found eight pointing off the domain, and not one of them was ours.
All of that is accurate. The conclusion was still wrong.
AlternativeTo puts the outbound link on a sub-page. Our main listing has none; /about/ carries Official Website pointing at our domain with rel="nofollow noopener". I only found it because I went looking for a form to add the missing URL, opened the edit view, and discovered the URL had been stored correctly all along. A well established listing on the same site behaves identically, so this is how the site works, not a quirk of ours.
My script had one job, read the outbound links of a listing, and it read the outbound links of exactly one page per listing: the address recorded in my ledger. It had never followed a sub-page in its life.
So the row moved from no link to nofollow. Then I rebuilt the sub-page search properly, ran it across every remaining no-link listing, and a second one fell the same way for a different reason.
One directory does link to us, through its own redirect script: an anchor reading https://blueticks.io whose href points at redir.php on their domain, carrying rel="nofollow". My script looked for an href containing our domain. This one does not contain it. The link is real, the rel is real, and my filter could not see either.
Two of the three no-link verdicts I re-examined turned out to be links hidden by a site convention, one on a sub-page and one behind a redirect. That is not a coincidence, it is what directories do: they route outbound traffic so they can measure it, and every routing scheme is invisible to a naive href match.
The remaining rows are hypotheses. The followed and nofollow rows are measurements.
This post was drafted alongside another one arguing that a crawler's negative result is a hypothesis rather than a fact. Its own principle caught it, one day later, in the table above.
The measurement that changed its mind
One domain flipped between two runs an hour apart. startupranking.com read as no link at 07:05 and as a followed link at 08:00.
That is the sort of thing you either chase down or quietly average away. I ran it three more times: followed, followed, followed, with an empty rel attribute each time. The first reading was a false negative, because eleven seconds is not enough for that site to finish loading, and my script measured an empty page.
The consequence is not that one number changed. It is that every negative verdict this script produces is suspect, because a negative verdict and a slow page look identical. So I re-ran all nine of the no-link pages a second time. They held, at the level my script was capable of checking, which the previous section shows was not the level I thought. Had I not chased the one that flipped, I would have published a table with a wrong row in it and no way of knowing which.
A positive result from this kind of script is evidence. A negative result is a hypothesis.
Two counting mistakes, both caught by a total
While tallying the results I wrote a small parser to group them by domain. It reported 28 addresses. The run had measured 24.
The parser was matching the summary lines at the bottom of the output as if they were results, adding one phantom row to every category. Nothing about the output looked wrong. The categories were plausible, the proportions were plausible, and the only thing that gave it away was that 28 is not 24.
Then, separately, I ran the script on a single URL to double check one site, and it overwrote the JSON file holding all 24 results, because the output path was a constant.
Neither of these is interesting on its own. Together they are the reason I now keep a total in every summary I print, even when nothing consumes it. The total is not for the reader. It is the only thing standing between a plausible table and a wrong one.
What I would do differently, and what I would not
I would still make the submissions. They took a few nights, they cost nothing, and four indexable followed links from real software directories is a reasonable return for that.
What I would change is the bookkeeping. A listing goes into the ledger with its rel value from day one, not twelve days later. Without that column the ledger says 58 and means five, and every decision downstream, where to submit next, whether the vein is exhausted, whether it is worth another night, is being made on the wrong number.
The vein is nearly exhausted, incidentally. Five search passes across pages that mention comparable tools returned fifty linked domains on its last pass and zero we did not already know. That is a real signal to stop, and it is only legible once you stop counting pages and start counting links.
One of them was my own empty field
After finishing the table I did something I had not done once in twelve days of measuring these listings: I asked whether I could change any of them.
We hold accounts on several of these directories. On one, a profile page carrying our name and no link, the website field in the settings was simply blank. I filled it in, saved, reloaded to confirm it had stored, and then loaded the public page in an anonymous context. The link is there now, with rel="noreferrer nofollow ugc".
So that row moves, and it moves for a reason that has nothing to do with the directory's policy. It was never a decision they made. It was a field I never filled.
I checked the others in the same spirit and the answers were varied and worth knowing. Two listings already had the correct URL stored and simply have not published yet, because the product is sitting in a launch queue. One company page has nineteen editable fields and not one of them is a website, so no link is possible there at all, which is a firm answer rather than a gap. One project page offers its owner no edit control I could find.
The useful lesson is not the row that moved. It is that I spent twelve days measuring an inventory without once asking which parts of it I controlled. Measuring and acting are different verbs, and I had been using only the first.
Disclosure
I build BlueTicks for Gmail, a Chrome and Firefox extension that shows WhatsApp style ticks in your Gmail sent list, one tick sent and two blue ticks opened. It costs 4 dollars a year and there is a free tier. The directory work described above is how it gets distributed, written up as it happens, including the parts that measure badly. You can find it at blueticks.io.
If you are running the same play, the check takes an afternoon: load each listing anonymously, read the rel, and count what you actually own.
Top comments (0)