{"id":42,"date":"2026-07-13T11:04:32","date_gmt":"2026-07-13T05:34:32","guid":{"rendered":"https:\/\/jnkplugins.com\/blog\/docs\/automatic-linker\/"},"modified":"2026-07-30T08:42:45","modified_gmt":"2026-07-30T03:12:45","slug":"jnk-linkweave","status":"publish","type":"page","link":"https:\/\/jnkplugins.com\/blog\/docs\/jnk-linkweave\/","title":{"rendered":"JnK Linkweave"},"content":{"rendered":"<p><a href=\"https:\/\/jnkplugins.com\/jnk-linkweave\/\" class=\"jnk-linkweave-auto\">JnK Linkweave<\/a> suggests and inserts internal links between your posts, entirely on your own server. This page covers how it decides what to link and the hooks you can use to shape that behaviour.<\/p>\n<h2>How suggestions are computed<\/h2>\n<p>JnK Linkweave builds an index of your content and scores candidate links using <strong>TF-IDF<\/strong> (term frequency\u2013inverse document frequency) with cosine similarity \u2014 a well-understood information-retrieval technique that runs locally, with no external API call. Posts whose vocabulary overlaps meaningfully with the current post surface as suggestions, ranked by relevance.<\/p>\n<p>An optional BYOK (&#8220;bring your own key&#8221;) LLM mode can refine suggestions using your own OpenAI or Anthropic key. It&#8217;s off by default; with no key configured, all suggestions come from the local TF-IDF engine and nothing leaves your server.<\/p>\n<h2>Indexing<\/h2>\n<p>The index is built in the background and refreshed as content changes. Suggestions are cached as transients keyed on the post id and its modified time, so repeat page loads don&#8217;t recompute. You control which post types are indexed and which are eligible link targets from the settings screen \u2014 or in code via the filters below.<\/p>\n<h2>Auto-linking rules<\/h2>\n<p>Beyond suggestions, you can define rules that automatically turn a phrase into a link at render time. Rules apply late on <code>the_content<\/code> (after block and page-builder output) and never touch text that&#8217;s already inside an anchor, heading, code block, or shortcode \u2014 those regions are swapped out as placeholders before substitution and restored afterward, so existing markup is preserved.<\/p>\n<h2>Public filters<\/h2>\n<p>These filters let you adjust behaviour without editing the plugin (names as documented in the plugin&#8217;s <code>readme.txt<\/code>):<\/p>\n<pre><code>automatic_linker_suggestion_post_types  \/\/ which post types are indexed\nautomatic_linker_allowed_post_types      \/\/ which post types are eligible targets\nautomatic_linker_suggestion_score        \/\/ adjust a candidate link's score\nautomatic_linker_rerank                  \/\/ reorder the final suggestion list\nautomatic_linker_max_active_rules        \/\/ cap on simultaneously active rules\nautomatic_linker_is_pro                  \/\/ gate Pro-only behaviour<\/code><\/pre>\n<h2>Public actions<\/h2>\n<pre><code>automatic_linker_rule_applied       \/\/ fires when an auto-link rule rewrites content\nautomatic_linker_suggestion_inserted \/\/ fires when a suggested link is inserted\nautomatic_linker_broken_link_found   \/\/ fires when the scanner finds a broken link<\/code><\/pre>\n<h2>Example: limit indexing to posts and a custom type<\/h2>\n<pre><code>add_filter( 'automatic_linker_suggestion_post_types', function ( array $types ) {\n    return [ 'post', 'guide' ];\n} );<\/code><\/pre>\n<h2>Reports<\/h2>\n<p>JnK Linkweave also scans for <strong>orphan<\/strong> content (posts nothing links to) and <strong>broken<\/strong> links, surfacing both as reports. The broken-link scan fires <code>automatic_linker_broken_link_found<\/code> as it goes, so you can log or notify on findings.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>JnK Linkweave suggests and inserts internal links between your posts, entirely on your own server. This page covers how it decides what to link and the \u2026<\/p>\n","protected":false},"author":0,"featured_media":0,"parent":5,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-42","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.0 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>JnK Linkweave - JnK Plugins Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/jnkplugins.com\/blog\/docs\/jnk-linkweave\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"JnK Linkweave - JnK Plugins Blog\" \/>\n<meta property=\"og:description\" content=\"JnK Linkweave suggests and inserts internal links between your posts, entirely on your own server. This page covers how it decides what to link and the \u2026\" \/>\n<meta property=\"og:url\" content=\"https:\/\/jnkplugins.com\/blog\/docs\/jnk-linkweave\/\" \/>\n<meta property=\"og:site_name\" content=\"JnK Plugins Blog\" \/>\n<meta property=\"article:modified_time\" content=\"2026-07-30T03:12:45+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/jnkplugins.com\\\/blog\\\/docs\\\/jnk-linkweave\\\/\",\"url\":\"https:\\\/\\\/jnkplugins.com\\\/blog\\\/docs\\\/jnk-linkweave\\\/\",\"name\":\"JnK Linkweave - JnK Plugins Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jnkplugins.com\\\/blog\\\/#website\"},\"datePublished\":\"2026-07-13T05:34:32+00:00\",\"dateModified\":\"2026-07-30T03:12:45+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/jnkplugins.com\\\/blog\\\/docs\\\/jnk-linkweave\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/jnkplugins.com\\\/blog\\\/docs\\\/jnk-linkweave\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/jnkplugins.com\\\/blog\\\/docs\\\/jnk-linkweave\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/jnkplugins.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Documentation\",\"item\":\"https:\\\/\\\/jnkplugins.com\\\/blog\\\/docs\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"JnK Linkweave\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/jnkplugins.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/jnkplugins.com\\\/blog\\\/\",\"name\":\"JnK Plugins Blog\",\"description\":\"Guides, comparisons, and tutorials for our WordPress plugins\",\"publisher\":{\"@id\":\"https:\\\/\\\/jnkplugins.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/jnkplugins.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/jnkplugins.com\\\/blog\\\/#organization\",\"name\":\"JnK Plugins\",\"url\":\"https:\\\/\\\/jnkplugins.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/jnkplugins.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/jnkplugins.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/jnkplugins-jk-logo-512.png\",\"contentUrl\":\"https:\\\/\\\/jnkplugins.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/jnkplugins-jk-logo-512.png\",\"width\":512,\"height\":512,\"caption\":\"JnK Plugins\"},\"image\":{\"@id\":\"https:\\\/\\\/jnkplugins.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.youtube.com\\\/@JnKPlugins\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/jnkplugins\\\/\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"JnK Linkweave - JnK Plugins Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/jnkplugins.com\/blog\/docs\/jnk-linkweave\/","og_locale":"en_US","og_type":"article","og_title":"JnK Linkweave - JnK Plugins Blog","og_description":"JnK Linkweave suggests and inserts internal links between your posts, entirely on your own server. This page covers how it decides what to link and the \u2026","og_url":"https:\/\/jnkplugins.com\/blog\/docs\/jnk-linkweave\/","og_site_name":"JnK Plugins Blog","article_modified_time":"2026-07-30T03:12:45+00:00","twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/jnkplugins.com\/blog\/docs\/jnk-linkweave\/","url":"https:\/\/jnkplugins.com\/blog\/docs\/jnk-linkweave\/","name":"JnK Linkweave - JnK Plugins Blog","isPartOf":{"@id":"https:\/\/jnkplugins.com\/blog\/#website"},"datePublished":"2026-07-13T05:34:32+00:00","dateModified":"2026-07-30T03:12:45+00:00","breadcrumb":{"@id":"https:\/\/jnkplugins.com\/blog\/docs\/jnk-linkweave\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/jnkplugins.com\/blog\/docs\/jnk-linkweave\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/jnkplugins.com\/blog\/docs\/jnk-linkweave\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/jnkplugins.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Documentation","item":"https:\/\/jnkplugins.com\/blog\/docs\/"},{"@type":"ListItem","position":3,"name":"JnK Linkweave"}]},{"@type":"WebSite","@id":"https:\/\/jnkplugins.com\/blog\/#website","url":"https:\/\/jnkplugins.com\/blog\/","name":"JnK Plugins Blog","description":"Guides, comparisons, and tutorials for our WordPress plugins","publisher":{"@id":"https:\/\/jnkplugins.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/jnkplugins.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/jnkplugins.com\/blog\/#organization","name":"JnK Plugins","url":"https:\/\/jnkplugins.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/jnkplugins.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/jnkplugins.com\/blog\/wp-content\/uploads\/2026\/08\/jnkplugins-jk-logo-512.png","contentUrl":"https:\/\/jnkplugins.com\/blog\/wp-content\/uploads\/2026\/08\/jnkplugins-jk-logo-512.png","width":512,"height":512,"caption":"JnK Plugins"},"image":{"@id":"https:\/\/jnkplugins.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.youtube.com\/@JnKPlugins","https:\/\/www.linkedin.com\/company\/jnkplugins\/"]}]}},"_links":{"self":[{"href":"https:\/\/jnkplugins.com\/blog\/wp-json\/wp\/v2\/pages\/42","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jnkplugins.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/jnkplugins.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"replies":[{"embeddable":true,"href":"https:\/\/jnkplugins.com\/blog\/wp-json\/wp\/v2\/comments?post=42"}],"version-history":[{"count":2,"href":"https:\/\/jnkplugins.com\/blog\/wp-json\/wp\/v2\/pages\/42\/revisions"}],"predecessor-version":[{"id":217,"href":"https:\/\/jnkplugins.com\/blog\/wp-json\/wp\/v2\/pages\/42\/revisions\/217"}],"up":[{"embeddable":true,"href":"https:\/\/jnkplugins.com\/blog\/wp-json\/wp\/v2\/pages\/5"}],"wp:attachment":[{"href":"https:\/\/jnkplugins.com\/blog\/wp-json\/wp\/v2\/media?parent=42"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}