{"id":381076,"date":"2025-12-30T20:10:13","date_gmt":"2025-12-30T20:10:13","guid":{"rendered":"https:\/\/www.newsbeep.com\/au\/381076\/"},"modified":"2025-12-30T20:10:13","modified_gmt":"2025-12-30T20:10:13","slug":"free-ai-wordpress-plugin-to-automate-internal-linking-for-seos","status":"publish","type":"post","link":"https:\/\/www.newsbeep.com\/au\/381076\/","title":{"rendered":"Free AI WordPress Plugin To Automate Internal Linking For SEOs"},"content":{"rendered":"<p>If you\u2019ve been following this series of exploration of vectors and their application in SEO, we have covered the building blocks of the plugin I\u2019m sharing with you:<\/p>\n<p><a href=\"https:\/\/www.searchenginejournal.com\/llm-embeddings-seo\/518297\/\" rel=\"nofollow noopener\" target=\"_blank\">Understanding the basics<\/a>.<br \/>\n<a href=\"https:\/\/www.searchenginejournal.com\/find-keyword-cannibalization-using-openai-text-embeddings-examples\/520274\/\" rel=\"nofollow noopener\" target=\"_blank\">Solving content issues<\/a>.<br \/>\n<a href=\"https:\/\/www.searchenginejournal.com\/introduction-to-vector-databases-and-how-to-use-ai-for-seo\/533993\/\" rel=\"nofollow noopener\" target=\"_blank\">Scaling up to handle massive amounts of data<\/a>.<br \/>\n<a href=\"https:\/\/www.searchenginejournal.com\/how-to-use-llms-for-301-redirects-at-scale\/546159\/\" rel=\"nofollow noopener\" target=\"_blank\">Automating 301 redirects at scale.<\/a><\/p>\n<p>Running Python scripts in a terminal is powerful, but it isn\u2019t where SEOs and content writers spend most of their day, and there has been a friction point. It wasn\u2019t accessible.<\/p>\n<p>We are bringing what we learned directly into your WordPress, a content management system which powers <a href=\"https:\/\/www.searchenginejournal.com\/cms-market-share\/454039\/\" rel=\"nofollow noopener\" target=\"_blank\">43.3%<\/a> of the web.<\/p>\n<p>I built a functional proof-of-concept WordPress plugin with AI assistance, using Google Vertex AI, OpenAI, and Pinecone APIs to manage internal linking directly inside the WordPress editor. Today, I\u2019m sharing exactly how it works, the logic behind the code, and the plugin files for you to experiment with.<\/p>\n<p><a data-u=\"internal-linking-plugin\" href=\"#dwn\" title=\"Click to download! If you want to share this, please share the article link\">Download the ZIP<\/a><\/p>\n<p>Let\u2019s dive into the setup, and learn how to make the plugin work, and anyone with no technical background can do that.<\/p>\n<p>1. Create A Pinecone Vector Database<\/p>\n<p>We covered how to work in Pinecone <a href=\"https:\/\/www.searchenginejournal.com\/introduction-to-vector-databases-and-how-to-use-ai-for-seo\/533993\/\" rel=\"nofollow noopener\" target=\"_blank\">vector database<\/a> in the previous chapter, in case you want to have a more in-depth look. But registering is quite simple and straightforward; just <a href=\"https:\/\/www.pinecone.io\/\" target=\"_blank\" rel=\"noopener nofollow\">visit their website<\/a> and sign up. Create a table with any name you prefer, with a custom dimensionality of 768.<\/p>\n<p>To set up the plugin, you would need:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.newsbeep.com\/au\/wp-content\/uploads\/2025\/12\/pinecone-database-host-926.png\" alt=\"Pinecone table with dimensionality of 768\" width=\"1627\" height=\"707\" class=\"wp-image-564132 size-full\"   loading=\"lazy\"\/>Pinecone table with dimensionality of 768 (Image from author, December 2025)<br \/>\n2. Create An OpenAI API Key<\/p>\n<p>Log in to <a href=\"https:\/\/platform.openai.com\/\" target=\"_blank\" rel=\"noopener nofollow\">platform.openai.com<\/a> and navigate to the Settings &gt; Billing section. You must add a small credit balance (e.g., $5) to your account, as the API will not work without a payment method attached. We pay about $0.5\/month for OpenAI API usage.<\/p>\n<p><a href=\"https:\/\/platform.openai.com\/api-keys\" target=\"_blank\" rel=\"noopener nofollow\">Generate the key<\/a> by clicking on \u201cCreate new secret key\u201d and give your key a name (like \u201cWP Internal Link Plugin\u201d) and copy the string immediately, as you will not be able to view it again once the window closes.<\/p>\n<p>3. Google Service Account JSON Key<\/p>\n<p>You need to go to <a href=\"https:\/\/console.cloud.google.com\/\" target=\"_blank\" rel=\"noopener nofollow\">Google Cloud Console<\/a> and enable \u201cVertex AI API\u201d by navigating to <a href=\"https:\/\/console.cloud.google.com\/vertex-ai\/dashboard\" target=\"_blank\" rel=\"noopener nofollow\">this URL<\/a>. Please note Google requires a billing account for AI services, even if you stay within the free tier. Search for \u201cBilling\u201d in the top search bar and add the credit card information by following the required steps. We pay around $0.3\/month for Vertex API usage.<\/p>\n<p>Once you\u2019ve done that, navigate to \u201cAPI &amp; Services\u201d and create \u201cService Account\u201d JSON key you need to copy and paste in the settings. You can <a href=\"https:\/\/www.youtube.com\/shorts\/BBgrgA96n-Q\" target=\"_blank\" rel=\"noopener nofollow\">watch this video<\/a> on how it is done if you have a hard time to navigate in Google Cloud Console.<\/p>\n<p>4. Plugin Configuration<\/p>\n<p>Once you\u2019ve set up all accounts and gathered all the keys, it is time to install the zip file and set up the settings in the plugin. (It is always recommended to install new plugins on staging website first.)<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.newsbeep.com\/au\/wp-content\/uploads\/2025\/12\/admin-setting-of-internal-linking-plugin-502.png\" alt=\"Plugin Settings Page (Image from author, December 2025)\" width=\"1920\" height=\"1257\" class=\"wp-image-564180 size-full\"   loading=\"lazy\"\/>Plugin Settings Page (Image from author, December 2025)<\/p>\n<p>You can also select post types you want to index, which gives you even more granular control over the articles you will index.<\/p>\n<p>Basically, we could use the same Google service account keys to replace the OpenAI API with Gemini, but I used OpenAI on purpose so you would engage, create an API key there, and learn how to do it.<\/p>\n<p>4. Indexing: Moving Content To The Vector DB<\/p>\n<p>Before we can search for links, our existing content must exist as vectors in the vector database you\u2019ve created.<\/p>\n<p>In Part 3 of this series, we learned <a href=\"https:\/\/www.searchenginejournal.com\/introduction-to-vector-databases-and-how-to-use-ai-for-seo\/533993\/\" rel=\"nofollow noopener\" target=\"_blank\">how to upsert vectors into Pinecone<\/a> manually. This plugin automates that process, and you no longer need Python scripts.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.newsbeep.com\/au\/wp-content\/uploads\/2025\/12\/upsert-articles-into-pinecone-432.png\" alt=\"Upsert articles into pinecone\" width=\"1735\" height=\"696\" class=\"wp-image-564133 size-full\"   loading=\"lazy\"\/>Upsert articles into Pinecone (Image from author, December 2025)<\/p>\n<p>When you run the initial indexing, the plugin iterates through your published WordPress posts and pages. It parses the DOM structure of each post to extract strategically important content sections, concatenating them into a single text representation that gets <a href=\"https:\/\/www.searchenginejournal.com\/introduction-to-vector-databases-and-how-to-use-ai-for-seo\/533993\/#:~:text=2.%20Export%20Your,improve%20retrieval%20quality.\" rel=\"nofollow noopener\" target=\"_blank\">embedded as a vector:<\/a><\/p>\n<p>The title.<br \/>\nYoast SEO meta description (if present).<br \/>\nExcerpt.<br \/>\nFirst opening paragraph.<br \/>\nEach H2 heading, along with its subsequent paragraph.<\/p>\n<p>This ensures that vectors focus on the article\u2019s primary topics rather than being diluted by background context. Afterwards, it sends the composed copy to the embedding model to generate a numerical vector representation (768 dimensions), and stores that vector in Pinecone along with the post ID and title (here you may consider tweaking the functionality and instead of the content push only Yoast meta description).<\/p>\n<p>The plugin makes <a href=\"https:\/\/docs.cloud.google.com\/vertex-ai\/generative-ai\/docs\/embeddings\/batch-prediction-genai-embeddings\" target=\"_blank\" rel=\"noopener nofollow\">batch requests<\/a> for efficiency. To give you a sense of indexing speed, it indexed 25,000 articles in about 50 minutes. Alternatively, if you have a few hundred thousand pages, you may want to export them and upsert using a Jupyter notebook, as <a href=\"https:\/\/www.searchenginejournal.com\/introduction-to-vector-databases-and-how-to-use-ai-for-seo\/533993\/#:~:text=Next%2C%20you%20will%20need%20to%20use%20Jupyter%20Notebook.%20If%20you%20don%E2%80%99t%20have%20it%20installed%2C%20follow%20this%20guide%20to%20install%20it%20and%20run%20this%20command%20(below)%20afterward%20in%20your%20PC%E2%80%99s%20terminal%20to%20install%20all%20necessary%20packages.\" rel=\"nofollow noopener\" target=\"_blank\">described here<\/a>.<\/p>\n<p>It is a one-time heavy job that needs to be done, later, when you hit \u201cUpdate\u201d or \u201cPublish\u201d in WordPress, the plugin instantly generates a new vector for that specific post and updates the record. It will delete the record if you delete the article. It ensures that your index is always up to date.<\/p>\n<p>I would like to note that indexing will be a little expensive, perhaps around $1 to $2 for a few tens of thousands of articles, but it is a one-time expense for the initial setup.<\/p>\n<p>Now it is time to add internal links to your content. This is where the fun part starts.<\/p>\n<p>The plugin has two modes of operation:<\/p>\n<p>Internal linking by manually selected anchor phrase.<br \/>\nAutomatically suggesting internal links by parsing the content of the article.<\/p>\n<p>And I know the WordPress community is still divided on Classic and Gutenberg editors, so I ensured the plugin works for both.<\/p>\n<p>5. Adding Internal Links In WordPress Gutenberg Editor<\/p>\n<p>In Gutenberg, it utilizes a sidebar panel for automatic internal link suggestions, and if you want to add an internal link for the phrase you\u2019ve chosen, click on the pencil icon.<\/p>\n<p>You can configure categories to filter the search, e.g., only suggest links from the \u201cAnalytics\u201d category, which serves as a sort of RAG to increase results accuracy.<\/p>\n<p>You also have the option to filter by article freshness, such as selecting articles published within a year or two, which can help you fetch fresh content linking ideas when dealing with news articles.<\/p>\n<p>\t\t\t\t<a href=\"https:\/\/www.newsbeep.com\/au\/wp-content\/uploads\/2025\/12\/run-automatic-internal-link-suggestion-6.png\" target=\"_blank\"><img decoding=\"async\" width=\"1920\" height=\"912\" src=\"https:\/\/www.newsbeep.com\/au\/wp-content\/uploads\/2025\/12\/run-automatic-internal-link-suggestion-6.png\" class=\"attachment-full size-full\" alt=\"Run automatic internal link suggestion\" aria-describedby=\"gallery-1-564134\"   loading=\"lazy\"\/><\/a><\/p>\n<p>\t\t\t\tRun automatic internal link suggestion (Image from author, December 2025)<\/p>\n<p>\t\t\t\t<a href=\"https:\/\/www.newsbeep.com\/au\/wp-content\/uploads\/2025\/12\/gutenberg-editor-actions-link-bulk-suggest-result-actions-393.png\" target=\"_blank\"><img decoding=\"async\" width=\"1913\" height=\"830\" src=\"https:\/\/www.newsbeep.com\/au\/wp-content\/uploads\/2025\/12\/gutenberg-editor-actions-link-bulk-suggest-result-actions-393.png\" class=\"attachment-full size-full\" alt=\"LLM-based automatic internal link suggestions.\" aria-describedby=\"gallery-1-564136\"   loading=\"lazy\"\/><\/a><\/p>\n<p>\t\t\t\tLLM-based automatic internal link suggestions. (Image from author, December 2025)<\/p>\n<p>\t\t\t\t<a href=\"https:\/\/www.newsbeep.com\/au\/wp-content\/uploads\/2025\/12\/gutenberg-editor-actions-link-by-selected-phrase-617.png\" target=\"_blank\"><img decoding=\"async\" width=\"1901\" height=\"904\" src=\"https:\/\/www.newsbeep.com\/au\/wp-content\/uploads\/2025\/12\/gutenberg-editor-actions-link-by-selected-phrase-617.png\" class=\"attachment-full size-full\" alt=\"Internal linking on manually selected anchor phrase.\" aria-describedby=\"gallery-1-564135\"   loading=\"lazy\"\/><\/a><\/p>\n<p>\t\t\t\tInternal linking on manually selected anchor phrase. (Image from author, December 2025)<\/p>\n<p>\t\t\t\t<a href=\"https:\/\/www.newsbeep.com\/au\/wp-content\/uploads\/2025\/12\/gutenberg-editor-actions-link-by-selected-phrase-suggestions-popup-204.png\" target=\"_blank\"><img decoding=\"async\" width=\"1920\" height=\"912\" src=\"https:\/\/www.newsbeep.com\/au\/wp-content\/uploads\/2025\/12\/gutenberg-editor-actions-link-by-selected-phrase-suggestions-popup-204.png\" class=\"attachment-full size-full\" alt=\"Pop up with suggestions\" aria-describedby=\"gallery-1-564137\"   loading=\"lazy\"\/><\/a><\/p>\n<p>\t\t\t\tPop up with suggestions. (Image from author, December 2025)<\/p>\n<p>Once you set the filters and run bulk suggestions, it uses OpenAI\u2019s \u201cGPT-4.1-nano\u201d model for <a href=\"https:\/\/www.searchenginejournal.com\/sentence-level-semantic-internal-links-strategy\/506771\/\" rel=\"nofollow noopener\" target=\"_blank\">anchor text extraction<\/a>\u00a0that populates the sidebar, where you will find the \u201cApply\u201d button to insert the link seamlessly on the phrase in the editor.<\/p>\n<p>This is what happens under the hood.<\/p>\n<p>Entity Extraction: When you click \u201cBulk Auto Suggestion,\u201d the plugin sends the current content of your draft to the OpenAI API to extract \u201centities\u201d and \u201ckey phrases\u201d that are relevant to the article\u2019s topic.<br \/>\nVectorization using Google Vertex AI: The plugin takes that specific phrase and converts it into a vector.<br \/>\nVector Search: It queries Pinecone for articles using the vector it created in your database.<br \/>\nResult: It returns the most relevant articles, even if they don\u2019t contain those exact words that are semantically close to that phrase.<\/p>\n<p>6. Adding LLMs-Based Internal Links In WordPress Classic Editor<\/p>\n<p>In the Classic Editor, the process is similar; you get a dedicated \u201cSuggest Links\u201d dropdown in the toolbar.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.newsbeep.com\/au\/wp-content\/uploads\/2025\/12\/adding-llm-based-internal-links-in-classic-editor.-126.png\" alt=\"Adding LLM-based internal links in Classic Editor.\" width=\"1918\" height=\"856\" class=\"wp-image-564139 size-full\"   loading=\"lazy\"\/>Adding LLM-based internal links in Classic Editor. (Image from author, December 2025)<\/p>\n<p>And in the same way, you can use each option. You can just select any phrase in the editor and click on \u201cSuggest by Anchor Text\u201d or run \u201cBulk Auto Suggestion.\u201d<\/p>\n<p>\t\t\t\t<a href=\"https:\/\/www.newsbeep.com\/au\/wp-content\/uploads\/2025\/12\/classic-editor-actions-link-bulk-suggest-351.png\" target=\"_blank\"><img decoding=\"async\" width=\"1920\" height=\"886\" src=\"https:\/\/www.newsbeep.com\/au\/wp-content\/uploads\/2025\/12\/classic-editor-actions-link-bulk-suggest-351.png\" class=\"attachment-full size-full\" alt=\"Bulk auto suggestion in Classic Editor\" aria-describedby=\"gallery-2-564141\"   loading=\"lazy\"\/><\/a><\/p>\n<p>\t\t\t\tBulk auto suggestion in Classic Editor. (Image from author, December 2025)<\/p>\n<p>\t\t\t\t<a href=\"https:\/\/www.newsbeep.com\/au\/wp-content\/uploads\/2025\/12\/classic-editor-actions-link-by-selected-phrase-706.png\" target=\"_blank\"><img decoding=\"async\" width=\"1920\" height=\"912\" src=\"https:\/\/www.newsbeep.com\/au\/wp-content\/uploads\/2025\/12\/classic-editor-actions-link-by-selected-phrase-706.png\" class=\"attachment-full size-full\" alt=\"Internal Linking on User Selected Phrase\" aria-describedby=\"gallery-2-564143\"   loading=\"lazy\"\/><\/a><\/p>\n<p>\t\t\t\tInternal Linking on User Selected Phrase. (Image from author, December 2025)<\/p>\n<p>Quite easy and fun to add internal links now, isn\u2019t it?<\/p>\n<p>7. Alternatives<\/p>\n<p>There are a number of options, either free or paid, you may want to explore, such as:<\/p>\n<p><a href=\"https:\/\/wordpress.org\/plugins\/link-whisper\/\" target=\"_blank\" rel=\"noopener nofollow\">Link Whisper<\/a>.<br \/>\n<a href=\"https:\/\/www.youtube.com\/watch?v=RwqJnhfLUXw\" target=\"_blank\" rel=\"noopener nofollow\">Plugli<\/a>.<br \/>\n<a href=\"https:\/\/www.youtube.com\/watch?v=HLRIz9s4XvM\" target=\"_blank\" rel=\"noopener nofollow\">Yoast Premium<\/a>.<\/p>\n<p>And you may ask why we didn\u2019t use one of the existing solutions, but preferred to build one from scratch. The answer is simple: We needed granular control over the output, and none of the plugins met our needs. Thus, we built one that we can fine-tune, flex, and control 100% as we want.<\/p>\n<p>And of course, it is free (apart from run costs), and we are independent from third parties. Below is the fee we pay for Google Vertex usage for a month of usage.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.newsbeep.com\/au\/wp-content\/uploads\/2025\/12\/costs-google-vertex-513.png\" alt=\"Google Cloud Console Fee\" width=\"1511\" height=\"240\" class=\"wp-image-562545 size-full\"   loading=\"lazy\"\/>Google Cloud Console Fee (Image from author, December 2025)<\/p>\n<p>To avoid any unpredictable cost spikes, it is always best practice to set <a href=\"https:\/\/docs.cloud.google.com\/billing\/docs\/how-to\/budgets\" target=\"_blank\" rel=\"noopener nofollow\">budget alerts<\/a>.<\/p>\n<p>Conclusion: From Embeddings To A Functional WordPress Plugin<\/p>\n<p>We moved from understanding the math of embeddings to building a fully functional LLM-based WordPress plugin that manages semantic internal linking.<\/p>\n<p>This plugin is a culmination of that knowledge. It is a functional foundation. I am sharing <a data-u=\"internal-linking-plugin\" href=\"#dwn\" title=\"Click to download! If you want to share this, please share the article link\">the zip file<\/a> not as a commercial product, but as an educational tool and a base for the community.<\/p>\n<p>Please note that this is a plugin created for educational purposes to demonstrate the power of LLMs and Vector Databases in SEO, and there is no official support provided for this plugin. It does not collect, store, or share any data with us or any third party. All data remains under the site owner\u2019s full ownership and control.<\/p>\n<p>However, if you have questions about the code, or want to discuss how you can extend its functionality, feel free to reach out to me <a href=\"https:\/\/www.linkedin.com\/in\/vahan-petrosyan-8a14116b\/\" target=\"_blank\" rel=\"noopener nofollow\">on LinkedIn<\/a>.\u00a0I will do my best to answer questions and help you troubleshoot as much as my time will let me do that.<\/p>\n<p>Happy internal linking!<\/p>\n<p>More Resources:<\/p>\n<p>Featured Image: Collagery\/Shutterstock<\/p>\n","protected":false},"excerpt":{"rendered":"If you\u2019ve been following this series of exploration of vectors and their application in SEO, we have covered&hellip;\n","protected":false},"author":2,"featured_media":381077,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20],"tags":[256,254,255,64,63,105],"class_list":{"0":"post-381076","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-artificial-intelligence","8":"tag-ai","9":"tag-artificial-intelligence","10":"tag-artificialintelligence","11":"tag-au","12":"tag-australia","13":"tag-technology"},"_links":{"self":[{"href":"https:\/\/www.newsbeep.com\/au\/wp-json\/wp\/v2\/posts\/381076","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.newsbeep.com\/au\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.newsbeep.com\/au\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.newsbeep.com\/au\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.newsbeep.com\/au\/wp-json\/wp\/v2\/comments?post=381076"}],"version-history":[{"count":0,"href":"https:\/\/www.newsbeep.com\/au\/wp-json\/wp\/v2\/posts\/381076\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.newsbeep.com\/au\/wp-json\/wp\/v2\/media\/381077"}],"wp:attachment":[{"href":"https:\/\/www.newsbeep.com\/au\/wp-json\/wp\/v2\/media?parent=381076"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.newsbeep.com\/au\/wp-json\/wp\/v2\/categories?post=381076"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.newsbeep.com\/au\/wp-json\/wp\/v2\/tags?post=381076"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}