DEV Community

Daniel Pertu
Daniel Pertu

Posted on

Our footer disclaims affiliation with every vendor, and our JSON-LD lists two of them as our other names

CogniPrep started as practice for one assessment vendor and now covers 56. The provider count is derived rather than typed, which is the part that aged well:

export const PROVIDER_COUNT = ALL_PROVIDERS.length;
Enter fullscreen mode Exit fullscreen mode

What did not age is the identity. Every public page renders one application/ld+json block from the root layout, and inside it:

name: 'CogniPrep',
alternateName: [
  'CogniPrep Psychometric Practice',
  'Arctic Shores Practice Platform',
  'SHL Practice Tests',
  'Psychometric Test Prep',
],
Enter fullscreen mode Exit fullscreen mode

Four values. One is a name the company could plausibly be known by. The other three are search phrases, and two of those name a vendor's trademark. schema.org defines alternateName as "an alias for the item", and we are not an alias for Arctic Shores or for SHL. We simulate their test formats, which is a different sentence entirely.

The reason this is worse than ordinary keyword stuffing is sitting in the footer of the exact same page:

CogniPrep is an independent practice platform and is not affiliated with or endorsed by any assessment provider, interview platform or employer. All product, company and trademark names are the property of their respective owners and are used for identification only.

So each page makes a careful disclaimer in prose for humans, and an unqualified identity claim in JSON for machines. A crawler reads the second one. You can see both in one request:

curl -s https://cogniprep.app/pricing | grep -c 'Arctic Shores Practice Platform'
curl -s https://cogniprep.app/pricing | grep -c 'not affiliated with or endorsed'
Enter fullscreen mode Exit fullscreen mode

Both return 1, on /pricing, on /tests, on /blogs, on a provider hub like /games/wonderlic and on all 375 URLs in the sitemap, because the node is in the layout rather than in any page.

The rest of the node is fine, which is what made it invisible

The same object carries knowsAbout with 27 entries and a hasOfferCatalog with 4 Course items. Those vendor names are descriptions of subject matter rather than claims about who we are:

knowsAbout: [
  'Arctic Shores Assessments',
  'SHL Verify Tests',
  ...
  // Non-branded formats, matching the /tests cluster. Without these
  // the entity is described purely in vendor names, which is not how
  // most candidates describe the test they have been sent.
  'Numerical Reasoning Tests',
  'Situational Judgement Tests',
  ...
]
Enter fullscreen mode Exit fullscreen mode

"We know about SHL Verify tests" is true and checkable against the pages. "We are also called SHL Practice Tests" is neither. One field is about the topic, the other is about the entity, and when a file is 60 lines of plausible JSON the difference stops being visually obvious. The review that catches it is not "is this accurate", it is "which field am I putting this in".

Where naming a vendor is a fact

This is not a post about scrubbing vendor names from a site. Most of them are load bearing, and they are governed.

64 of our 132 employer guides carry their own trademark notice naming the specific vendors on that page:

CogniPrep is an independent practice platform. It is not affiliated with, endorsed by or connected to Kroger or HireVue. Kroger is a trademark of its respective owner and is used for identification only.

And the page titles that pair an employer with a vendor are backed by a citation file where every association carries a URL somebody opened. "Thales Arctic Shores Practice" is a title we can defend, because the Thales profile holds a first-party Arctic Shores case study. Check it at cogniprep.app/employers/thales.

The 68 employer pages without their own notice fall back to the footer, which covers them. The provider hubs, none of which carry one, do the same. That spread is worth a look on its own: only 19 of the 64 are US-market pages, so it is not a market rule, it is a habit that started somewhere and was never backfilled.

The other leftovers from the one-vendor era

Once you know what to grep for, the pattern shows up wherever a string was typed early and never derived.

/help is a support page. Its description, served to search engines and to anyone pasting the link into a chat, reads:

Get help with CogniPrep. Contact our support team for questions about
Arctic Shores psychometric assessment practice, account issues, or
technical support.
Enter fullscreen mode Exit fullscreen mode

Its social card alt text is CogniPrep - Arctic Shores Practice Platform. Nothing about asking for help is vendor specific, and the one vendor it names is 1 of 56.

Then there is the file nobody reads, which is the best evidence of when the copy was last touched:

$ curl -s https://cogniprep.app/humans.txt
/* THANKS */
  Arctic Shores candidates worldwide
  Our beta testers and early adopters
  The open-source community

/* SITE */
  Last update: 2026/05/22
Enter fullscreen mode Exit fullscreen mode

That is honest about its own staleness, at least. The home page description, by contrast, interpolates PROVIDER_COUNT and names a rotating set of vendors, so it has stayed true through every provider launch without anyone editing it. The difference between the two is one template literal.

What I am changing

alternateName loses the two vendor phrases and keeps the one real alias. The knowsAbout list stays exactly as it is. The /help metadata drops the vendor entirely, because a support page has no provider. humans.txt gets the thanks line rewritten and the date removed, since a date you will not maintain is worse than no date.

The general rule I want is narrower than "keep metadata accurate". It is that a field describing who we are may not contain a name we do not own, while a field describing what we cover must contain exactly the names the pages can evidence. Those two rules are both assertable in the test suite, and one of them is about to be.

See it

Pull the whole Organization node out of any page and read the identity fields:

curl -s https://cogniprep.app/ \
  | grep -o '{"@context":"https://schema.org","@type":"Organization".\{0,400\}'
Enter fullscreen mode Exit fullscreen mode

You will get name, the four alternateName values and the start of a description that names 14 vendors out of the 56 the site actually covers. Then scroll to the bottom of the same page, where the footer says in words that we are connected to none of them. One of those two statements is going to change this week, and it is not the footer.

The site itself is at cogniprep.app, where the thing we are selling is practice for the test somebody else wrote, and saying precisely that in the markup is apparently a skill of its own.

Top comments (0)