One Person, Two Names, Three Domains: Engineering a Split Digital Identity
A pen name, a studio, and a personal archive are not a branding problem — they are an entity-graph problem. Here is how I keep search engines from turning three identities into one muddy blur.
I answer to more than one name on purpose. I write experimental fiction as Elian Voigt. I build software and run a studio called FORMÆTRIX. And I keep a personal engineering archive under my own name at ryanpyles.com. Three surfaces, one human. To a search engine, that is not a tidy story — it is three overlapping entities that will happily be merged, split, or confused unless you tell the machine, explicitly, how they relate.
There is a second wrinkle. Search for “Ryan Pyles software engineer” and you will find another engineer with the same name. Identity on the web is not resolved by how often you repeat your biography. It is resolved by structured, machine-readable claims. This is the architecture I use to make those claims — and the trap I engineered against.
Identity is an entity graph, not a bio
The instinct with multiple brands is to write one good biography and paste it on every domain. That is precisely the move that creates a muddy entity graph. Duplicated prose gives a search engine no signal about boundaries — where one identity ends and another begins — so it does the reasonable thing and blurs them together, or picks the wrong one as canonical.
The fix is to stop thinking in pages and start thinking in nodes and edges. There is one canonical Person node. It lives at exactly one URL. It claims its satellites — the studio, the pen name, the code profiles — with explicit typed edges. Everything else points home.
sameAs and worksFor. The pen name and the studio are separate nodes, connected — not duplicated.alternateName and sameAs do the real work
Two schema.org/Person properties carry most of the weight. alternateName resolves the fact that “Ryan Pyles” and “Ryan J. Pyles” are the same person — a small thing that quietly prevents the two spellings from fragmenting into two entities. sameAs is the load-bearing one: it is an explicit assertion that a list of URLs all refer to this identity. It is how you connect the studio and the pen name to the person without collapsing them into it.
// One canonical Person entity, declared once, that claims its own
// satellites. The alternateName resolves the two spellings of the name;
// sameAs is what tells a search engine these profiles are ONE identity.
export function buildPersonJsonLd(): string {
return JSON.stringify({
"@context": "https://schema.org",
"@type": "Person",
name: "Ryan Pyles",
alternateName: "Ryan J. Pyles",
url: "https://ryanpyles.com", // the canonical home
sameAs: [
"https://github.com/ryanpyles",
"https://www.linkedin.com/in/ryanpyles",
"https://www.formaetrix.com", // the studio
"https://www.elianvoigt.com", // the pen name
],
jobTitle: "Software Engineer & AI Systems Architect",
worksFor: { "@type": "Organization", name: "FORMÆTRIX" },
knowsAbout: ["AI Systems", "Next.js", "Publishing Infrastructure",
"Linguistics", "Experimental Fiction"],
});
}buildPersonJsonLd() from the site. knowsAbout is deliberate: it is disambiguation fuel against the other Ryan Pyles.knowsAbout and jobTitle are not decoration. When another person shares your name, generic identity signals are a coin flip. Specific, typed expertise — AI Systems, Next.js, Publishing Infrastructure, Linguistics — is what lets a search engine attach the right facts to the right Ryan. Technical specificity beats biographical volume every time.
One canonical URL per thing that exists
Structured data tells engines how entities relate. Canonicalization tells them which address is the original. Every page on the site declares exactly one canonical URL, and the host layer collapses the obvious duplicate — www — with a single permanent redirect. The rule is boring and absolute: nothing important is reachable at two addresses that both claim to be the source.
// Every page declares exactly one canonical URL. No page is reachable
// at two addresses that both claim to be the original.
alternates: { canonical: `https://ryanpyles.com${path}` }
// And at the host level, one 301 collapses the www duplicate:
// next.config — www.ryanpyles.com/:path -> ryanpyles.com/:path (permanent)The same discipline extends to the book pages, where the JSON-LD nests a Book inside an author Person and a publisher — so a novel is associated with a named author entity rather than a bare string. That nesting is what lets the fiction reinforce the person’s graph instead of floating free of it.
Where authorship boundaries actually matter
The point of separating the identities is not secrecy — it is clarity. Elian Voigt is the byline on the fiction; Ryan Pyles is the byline on the engineering. The technical writing you are reading is signed Ryan Pyles, consistently, because a stable byline is itself an entity signal. The pen name gets its own canonical home and its own graph; ryanpyles.com merely declares the connection. Cross-linking is one-directional discipline: each home claims the others, so the edges are asserted from a place that has the authority to assert them.
The short version
- Model identities as nodes and edges, not as repeated biographies.
- Use
alternateNameto fuse spellings of one name; usesameAsto connect distinct identities without merging them. - Give each entity one canonical home and collapse duplicate hosts with a 301.
- Lean on
knowsAbout/jobTitlefor disambiguation when you share a name with someone else. - Keep a consistent byline per surface — the byline is an entity signal.
The publishing side of this — one typed content model generating pages, Open Graph, and nested JSON-LD automatically — is its own build: Book SEO Architecture.