How I built a semantic scoring algorithm for internal links across >200 pages
Last week I wrote about why I added internal linking to my image converter. This is the technical follow-up: how I replaced alphabetical ordering with a semantic scoring algorithm. The problem with...

Source: DEV Community
Last week I wrote about why I added internal linking to my image converter. This is the technical follow-up: how I replaced alphabetical ordering with a semantic scoring algorithm. The problem with alphabetical ordering My RelatedConversions component was showing links in alphabetical order. For /heic-to-jpg, it would show avif-to-heic, avif-to-jpg, bmp-to-heic — technically related, but not semantically prioritized. What I wanted: show conversions that share the most format overlap first, then factor in keyword similarity. The scoring model: 70/30 A simple weighted formula: format overlap — how many formats the two conversions share (weight: 0.7) keyword similarity — do the slugs share meaningful terms (weight: 0.3) function scoreRelation(current, candidate) { const [fromA, toA] = current.split('-to-'); const [fromB, toB] = candidate.split('-to-'); const formatsA = new Set([fromA, toA]); const formatsB = new Set([fromB, toB]); const shared = [...formatsA].filter(f => formatsB.has(f