{"id":364965,"date":"2026-10-14T12:33:51","date_gmt":"2026-10-14T12:33:51","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/opptiai-internal-linking\/"},"modified":"2026-10-22T11:58:33","modified_gmt":"2026-10-22T11:58:33","slug":"opptiai-internal-linking","status":"publish","type":"plugin","link":"https:\/\/lt.wordpress.org\/plugins\/opptiai-internal-linking\/","author":11806311,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.1.4","stable_tag":"0.1.4","tested":"7.1.3","requires":"6.3","requires_php":"8.1","requires_plugins":null,"header_name":"OpptiAI Internal Linking \u2013 Find Orphan Pages for SEO","header_author":"OpptiAI","header_description":"AI internal linking for WordPress \u2014 scan your content, surface the links you are missing, and approve them in bulk. Draws on the shared OpptiAI credit wallet.","assets_banners_color":"f9fcfe","last_updated":"2026-10-22 11:58:33","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/oppti.dev\/plugins","header_author_uri":"https:\/\/oppti.dev","rating":0,"author_block_rating":0,"active_installs":0,"downloads":186,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"0.1.3":{"tag":"0.1.3","author":"beepbeepv2","date":"2026-10-14 14:57:52","revision":3746651},"0.1.4":{"tag":"0.1.4","author":"beepbeepv2","date":"2026-10-22 11:58:33","revision":3759842}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3746579,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3746579,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3746579,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3746579,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["0.1.3","0.1.4"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3746337,"resolution":"1","location":"assets","locale":"","width":1040,"height":760},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3746337,"resolution":"2","location":"assets","locale":"","width":1040,"height":760},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3746337,"resolution":"3","location":"assets","locale":"","width":1040,"height":760},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3746337,"resolution":"4","location":"assets","locale":"","width":1040,"height":640},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3746337,"resolution":"5","location":"assets","locale":"","width":1040,"height":980}},"screenshots":{"1":"Dashboard after a scan: pages scanned, internal links, and orphan pages.","2":"Pages list with inbound and outbound counts.","3":"Link map showing hubs and pages that are cut off.","4":"Opportunities: AI suggestions only run when you ask for a specific page.","5":"Settings: link caps, what to scan and the OpptiAI opt-in."}},"plugin_section":[],"plugin_tags":[19933,6681,11851,252136,186],"plugin_category":[55],"plugin_contributors":[256811],"plugin_business_model":[],"class_list":["post-364965","plugin","type-plugin","status-publish","hentry","plugin_tags-internal-linking","plugin_tags-internal-links","plugin_tags-link-building","plugin_tags-orphan-pages","plugin_tags-seo","plugin_category-seo-and-marketing","plugin_contributors-beepbeepv2","plugin_committers-beepbeepv2"],"banners":{"banner":"https:\/\/ps.w.org\/opptiai-internal-linking\/assets\/banner-772x250.png?rev=3746579","banner_2x":"https:\/\/ps.w.org\/opptiai-internal-linking\/assets\/banner-1544x500.png?rev=3746579","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/opptiai-internal-linking\/assets\/icon-128x128.png?rev=3746579","icon_2x":"https:\/\/ps.w.org\/opptiai-internal-linking\/assets\/icon-256x256.png?rev=3746579","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/opptiai-internal-linking\/assets\/screenshot-1.png?rev=3746337","caption":"Dashboard after a scan: pages scanned, internal links, and orphan pages."},{"src":"https:\/\/ps.w.org\/opptiai-internal-linking\/assets\/screenshot-2.png?rev=3746337","caption":"Pages list with inbound and outbound counts."},{"src":"https:\/\/ps.w.org\/opptiai-internal-linking\/assets\/screenshot-3.png?rev=3746337","caption":"Link map showing hubs and pages that are cut off."},{"src":"https:\/\/ps.w.org\/opptiai-internal-linking\/assets\/screenshot-4.png?rev=3746337","caption":"Opportunities: AI suggestions only run when you ask for a specific page."},{"src":"https:\/\/ps.w.org\/opptiai-internal-linking\/assets\/screenshot-5.png?rev=3746337","caption":"Settings: link caps, what to scan and the OpptiAI opt-in."}],"raw_content":"<!--section=description-->\n<p>https:\/\/www.youtube.com\/watch?v=fRwMftJy54Q<\/p>\n\n<p><strong>Find orphan pages in one scan. Runs in WordPress, no account, no credits.<\/strong><\/p>\n\n<p>An orphan page is a published post or page that no other page on your site links to, so visitors and search engines struggle to reach it. OpptiAI Internal Linking finds those pages, shows the internal links you already have, and lets you add a link after you review it.<\/p>\n\n<p>The scan runs on your site. It does not need an OpptiAI account, and it does not use credits. AI suggestions stay off until an administrator opts in and you ask for a specific page.<\/p>\n\n<p><strong>Two more free audits from OpptiAI:<\/strong> <a href=\"https:\/\/wordpress.org\/plugins\/beepbeep-ai-alt-text-generator\/\">OpptiAI Alt Text<\/a> shows how many of your images have no alt text, and <a href=\"https:\/\/wordpress.org\/plugins\/opptiai-titles\/\">OpptiAI Titles<\/a> checks for missing and duplicate SEO titles and meta descriptions. Both are free to try.<\/p>\n\n<h4>Features<\/h4>\n\n<ul>\n<li><strong>Free orphan page scan<\/strong> that lists published content with no inbound internal links. Pages linked from a navigation menu are not treated as orphans.<\/li>\n<li><strong>Inbound and outbound counts<\/strong> for every scanned post and page, including links inside blocks and shortcodes.<\/li>\n<li><strong>Link map<\/strong> that shows which pages are hubs and which are cut off.<\/li>\n<li><strong>Posts and pages by default<\/strong>, plus other public post types such as WooCommerce products if you enable them.<\/li>\n<li><strong>Apply only what you review:<\/strong> nothing is inserted on its own, and every apply saves a revision.<\/li>\n<li><strong>Optional AI link suggestions<\/strong> for a page you choose, after an administrator opts in.<\/li>\n<li><strong>One OpptiAI account<\/strong> shared with OpptiAI Alt Text and OpptiAI Titles if you already use them.<\/li>\n<\/ul>\n\n<h4>Find orphan pages<\/h4>\n\n<p>The scan lists published content with no inbound internal links. A page linked from a navigation menu is not treated as an orphan. This check stays in WordPress.<\/p>\n\n<h4>See your internal links<\/h4>\n\n<p>Every scanned post and page gets an inbound count and an outbound count. Links inside blocks and shortcodes are included. Posts and pages are scanned by default; you can add other public post types, including WooCommerce products. The link map shows which pages are hubs and which pages are cut off.<\/p>\n\n<h4>Apply a link you have reviewed<\/h4>\n\n<p>Nothing is inserted on its own. When you apply an approved internal link, the plugin never self-links, never nests inside an existing link, saves a revision, and follows your per-page link cap, minimum word count and excluded pages. If there is no safe place for the link, the post is left unchanged.<\/p>\n\n<p>AI link suggestions (the Opportunities screen) need an OpptiAI account, the administrator opt-in and an explicit request. They are free to try and use credits from your OpptiAI wallet; asking again for the same page within 30 minutes uses the saved result.<\/p>\n\n<p>If you already use <a href=\"https:\/\/wordpress.org\/plugins\/beepbeep-ai-alt-text-generator\/\">OpptiAI Alt Text<\/a> or <a href=\"https:\/\/wordpress.org\/plugins\/opptiai-titles\/\">OpptiAI Titles<\/a>, an administrator can share one OpptiAI account. The orphan page scan does not need that account.<\/p>\n\n<h4>Privacy<\/h4>\n\n<p>This plugin does not contact OpptiAI until an administrator enables \"Send page excerpts to OpptiAI\" and someone requests suggestions. It does not adopt credentials from Titles or Alt Text unless an administrator enables that in Settings. No personal visitor information is collected. Anonymous usage stats are sent only if an administrator turns on \"Share usage stats\" in Settings (off by default). See the External Services section for details.<\/p>\n\n<h3>External Services<\/h3>\n\n<p>This plugin connects to the OpptiAI API to generate internal-link suggestions and to report remaining service credits. AI generation is performed by the external service and is not performed locally by this plugin.<\/p>\n\n<p>Service: OpptiAI API\nService URL: https:\/\/alttext-ai-backend.onrender.com\nWebsite: https:\/\/oppti.dev\nPurpose: Generate internal-link suggestions between related pages, connect an OpptiAI account, and report available service credits.\nWhen data is sent: Only after an administrator enables \"Send page excerpts to OpptiAI\" in Settings, and only when an Editor or Administrator then requests AI suggestions for a page they can edit, or an administrator views remaining credits. Opening the plugin, scanning, viewing Pages or the Link Map, and applying an approved link do not contact the service.\nData sent: Site URL; plugin version; a pseudonymous installation and site identifier; a site fingerprint; the connected account license key (and an optional sibling JWT when the administrator has opted in to reuse a sibling account); and, for suggestions, the source page title, URL, a content excerpt, and candidate destination page titles, URLs, and IDs.\nPrivacy Policy: https:\/\/oppti.dev\/privacy\nTerms of Use: https:\/\/oppti.dev\/terms<\/p>\n\n<p>Service: PostHog (usage stats, opt-in only)\nService URL: https:\/\/us.i.posthog.com\nPurpose: Understand which features are used so OpptiAI can improve the plugin.\nWhen data is sent: Only after an administrator turns on \"Share usage stats\" in Settings. It is off by default, nothing is sent or queued before you opt in, and turning it off stops sending immediately.\nData sent: Feature usage events (plugin opened, scan finished, suggestions generated, links applied, first link inserted, settings saved) with counts only; the plugin, WordPress and PHP versions; whether an OpptiAI account is connected; and a random installation identifier. Never page content, titles, URLs, post IDs, emails, license keys or visitor data.\nPrivacy Policy: https:\/\/posthog.com\/privacy\nTerms of Use: https:\/\/posthog.com\/terms<\/p>\n\n<h3>Development<\/h3>\n\n<p>Human-readable source for the compiled admin app is included as <code>prototype\/*.jsx<\/code>. The bundle in <code>prototype\/dist\/app.bundle.js<\/code> is React and ReactDOM (production builds) followed by those files, each compiled from JSX with esbuild in the listed order. No other code is added.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Install the plugin from the Plugins screen, or upload it to <code>wp-content\/plugins\/opptiai-internal-linking<\/code>.<\/li>\n<li>Activate it through the <strong>Plugins<\/strong> menu in WordPress.<\/li>\n<li>Open <strong>OpptiAI Linking<\/strong> and run a scan. Orphan pages, the pages list, and the link map work with no account.<\/li>\n<li>To ask for AI link suggestions, an administrator enables \"Send page excerpts to OpptiAI\" in Settings. To reuse an account already connected by OpptiAI Titles or Alt Text, also enable \"Use sibling OpptiAI account\". Create an account at https:\/\/oppti.dev.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"what%20is%20an%20orphan%20page%3F\"><h3>What is an orphan page?<\/h3><\/dt>\n<dd><p>A published post or page with no internal link pointing to it from your other content. The scan lists those pages. A page linked from a navigation menu is not counted as an orphan.<\/p><\/dd>\n<dt id=\"do%20i%20need%20an%20account%20to%20find%20orphan%20pages%3F\"><h3>Do I need an account to find orphan pages?<\/h3><\/dt>\n<dd><p>No. The scan, the pages list and the link map run in WordPress and use no credits. An OpptiAI account is only used when you ask for an AI link suggestion.<\/p><\/dd>\n<dt id=\"is%20it%20free%3F\"><h3>Is it free?<\/h3><\/dt>\n<dd><p>Yes. Finding orphan pages, viewing your internal links and applying a link you have reviewed are free with no account. AI link suggestions are free to try with a free OpptiAI account, which includes a monthly suggestion allowance.<\/p><\/dd>\n<dt id=\"does%20this%20add%20internal%20links%20automatically%3F\"><h3>Does this add internal links automatically?<\/h3><\/dt>\n<dd><p>No. A link is inserted only when you apply a suggestion you have reviewed. Each apply saves a post revision, so you can undo it. When there is no safe match, the post is left unchanged.<\/p><\/dd>\n<dt id=\"does%20the%20scan%20cost%20credits%3F\"><h3>Does the scan cost credits?<\/h3><\/dt>\n<dd><p>No. Scanning, orphan detection and applying an approved link use no credits. Only AI link suggestions use credits from an OpptiAI account, and asking again for the same page within 30 minutes uses the saved result.<\/p><\/dd>\n<dt id=\"which%20content%20is%20scanned%3F\"><h3>Which content is scanned?<\/h3><\/dt>\n<dd><p>Posts and pages by default. You can enable additional public post types (for example WooCommerce products) under Settings &gt; Content to scan.<\/p><\/dd>\n<dt id=\"will%20this%20raise%20my%20search%20rankings%3F\"><h3>Will this raise my search rankings?<\/h3><\/dt>\n<dd><p>It shows you pages with no internal links and lets you add links you approve. It does not edit titles, metadata or sitemaps, and it does not promise higher rankings.<\/p><\/dd>\n<dt id=\"who%20can%20change%20settings%3F\"><h3>Who can change settings?<\/h3><\/dt>\n<dd><p>Editors can view content screens and settings; only administrators can save settings or view account and billing details. AI suggestions (Opportunities) are limited to Editors and Administrators, only for pages they can edit, and only those pages are offered as link targets. Applying a link requires permission to edit that specific post.<\/p><\/dd>\n<dt id=\"how%20do%20i%20connect%20an%20opptiai%20account%3F\"><h3>How do I connect an OpptiAI account?<\/h3><\/dt>\n<dd><p>You only need this for AI suggestions. In Settings, enable \"Use sibling OpptiAI account\" if OpptiAI Titles or Alt Text is already signed in on this site, then save. Also enable \"Send page excerpts to OpptiAI\" before requesting suggestions. Create an account at https:\/\/oppti.dev. Free includes a monthly suggestion allowance.<\/p><\/dd>\n<dt id=\"are%20there%20other%20opptiai%20plugins%3F\"><h3>Are there other OpptiAI plugins?<\/h3><\/dt>\n<dd><p>Yes, two more free audits. <a href=\"https:\/\/wordpress.org\/plugins\/beepbeep-ai-alt-text-generator\/\">OpptiAI Alt Text<\/a> shows how many of your images have no alt text, free to try. <a href=\"https:\/\/wordpress.org\/plugins\/opptiai-titles\/\">OpptiAI Titles<\/a> runs a free SEO health check for missing, duplicate and wrong-length titles and meta descriptions, next to Yoast, Rank Math or AIOSEO.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>0.1.4<\/h4>\n\n<ul>\n<li>Fix: block themes. Pages linked from the header or footer are no longer reported as orphans. The scan now reads Navigation blocks (including the default Page List), templates, template parts and synced patterns used there.<\/li>\n<li>The front page and posts page are never listed as orphans.<\/li>\n<li>The link map now draws cut-off pages that have no links in or out.<\/li>\n<li>Settings: the minimum word count help now says it applies to AI link suggestions only.<\/li>\n<li>After your first applied link, an optional one-time prompt to review the plugin on WordPress.org, and a pointer to the free OpptiAI Alt Text audit (hidden if Alt Text is active).<\/li>\n<li>Optional usage stats: an administrator can turn on \"Share usage stats\" in Settings (off by default). Nothing is sent without it.<\/li>\n<li>Release zip no longer includes build.js or package.json.<\/li>\n<\/ul>\n\n<h4>0.1.3<\/h4>\n\n<ul>\n<li>Readme: explain the local orphan-page scan, and that an account is only used for AI suggestions.<\/li>\n<li>Security: per-post permission checks on the REST API. AI link opportunities now require the Editor role (<code>edit_others_posts<\/code>) plus permission to edit the specific source post, checked in the route's permission callback; candidate pages sent to OpptiAI are limited to posts the current user can edit. Applying links checks <code>edit_post<\/code> for the post being edited in the permission callback, and only inserts links to published posts the user can edit.<\/li>\n<li>AI suggestions are only shown when their target is one of the candidate pages sent for that request.<\/li>\n<li>Reading plugin settings now requires the Editor role (<code>edit_others_posts<\/code>); saving still requires an administrator.<\/li>\n<li>Fix: applying a link now matches whole words only and inserts into visible text at most once. Matching is Unicode-aware (for example \"caf\u00e9\" or \"\u043a\u043e\u0448\u043a\u0430\"). It never touches HTML tags or attributes (such as image alt text), block comment markup, shortcodes, existing links, headings, code, scripts or styles. A post gets at most one link per target. When there is no safe match, the post is left unchanged.<\/li>\n<\/ul>\n\n<h4>0.1.2<\/h4>\n\n<ul>\n<li>Align the gettext text domain with the WordPress.org plugin slug (<code>opptiai-internal-linking<\/code>).<\/li>\n<\/ul>\n\n<h4>0.1.1<\/h4>\n\n<ul>\n<li>Require administrator opt-in before contacting OpptiAI or reusing a sibling plugin account.<\/li>\n<li>Opportunities no longer requests suggestions when the screen opens; you choose a page and ask.<\/li>\n<li>Credit quota is limited to administrators.<\/li>\n<li>Local scan, Pages, and Link Map work without an OpptiAI account.<\/li>\n<\/ul>\n\n<h4>0.1.0<\/h4>\n\n<ul>\n<li>Initial release: site scan, orphan detection, Pages and Link Map screens, persisted settings, shared OpptiAI wallet, AI Opportunities via the OpptiAI service, and a revision-safe apply-links route.<\/li>\n<\/ul>","raw_excerpt":"Find orphan pages in one scan. Runs in WordPress, no account, no credits. Then add the internal links you review.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/lt.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/364965","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lt.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/lt.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/lt.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=364965"}],"author":[{"embeddable":true,"href":"https:\/\/lt.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/beepbeepv2"}],"wp:attachment":[{"href":"https:\/\/lt.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=364965"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/lt.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=364965"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/lt.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=364965"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/lt.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=364965"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/lt.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=364965"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/lt.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=364965"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}