---
title: "Internal links"
description: "How Blogged proposes links between your own pages, why every destination is verified before it is offered, and how to insert one."
updated: "2026-08-20"
verifiedAgainst:
  - packages/shared/src/internal-links.ts
  - packages/shared/src/internal-link-inventory.ts
  - apps/web/lib/server/post-publication-effects.ts
  - apps/web/app/app/settings/internal-links/page.tsx
---

Internal links are the cheapest ranking work a blog can do, and the easiest to
get wrong by inventing a link to a page that does not exist.

## How opportunities are found

Blogged holds an inventory of destinations it has already verified exist. Link
opportunities are proposed only against that inventory, so a proposed
destination is always a real page.

Four kinds of destination are in it:

| Destination | Where it comes from |
| --- | --- |
| `post` | A post on your blog whose status is `published` |
| `category` | A category page on your blog, with posts filed under it |
| `product_page` | A page of your own product, from an active Knowledge Engine entity |
| `landing_page` | Another page of your own site, from the same source |

The last two are why a draft can link out to your pricing or feature pages
rather than only to other articles. They come from your own
[Knowledge Engine](/knowledge/overview), so a destination is offered only while
the entity behind it is active.

Each opportunity carries the destination, the anchor text, and the section of
the current article it belongs in, so inserting one puts the link where the
sentence supports it rather than at the end.

## Inserting

Accept an opportunity and the link is inserted into the matching section. Undo
puts it back. In the editor, nothing is inserted without you: every link that
appears there is one you accepted.

That is a statement about the editor and only about the editor. The automation
settings below can add links with nobody present, including to articles you have
already published.

## During generation

A drafting run proposes and inserts links using the same inventory. A brand new
blog has little to link to, which is normal: the inventory grows with the
archive, and older posts become link destinations for newer ones.

## Settings

Internal linking has its own settings under Project settings, Internal links.
Saving them requires the owner or admin role. An editor can open the page and
read the current values but cannot change them.

<Callout variant="warning" title="The default edits posts you have already published">
  `existingPublishedMode` defaults to `automatic`. On that setting, every time a
  post is published Blogged adds up to 10 safe link opportunities to your
  already published posts, editing live articles without anyone approving each
  link. It is a reasonable default and it is not a quiet one, so it is worth
  knowing you have it. If it is not what you want, set the mode to `review` and
  approve the links yourself, or to `off`.
</Callout>

<PropertyList>
  <Property name="newDraftMode" type="automatic | review | off">
    How links are added to new drafts. `automatic` wraps exact natural phrases
    once the article is written, `review` creates the same verified
    opportunities without touching the article, and `off` creates none.
  </Property>
  <Property name="existingPublishedMode" type="automatic | review | off">
    How links are added to posts that are **already published**, using the same
    three values. The default is `automatic`, which runs a bounded maintenance
    pass over your archive after each publication and applies up to 10 safe
    opportunities to it. If that pass fails, it is logged and the publication
    still succeeds: link maintenance never holds a post back.
  </Property>
  <Property name="includePublishedPosts" type="boolean">
    Whether the `post` row of the destination table above is eligible.
  </Property>
  <Property name="includeCategories" type="boolean">
    Whether the `category` row is eligible.
  </Property>
  <Property name="includeProductPages" type="boolean">
    Whether the `product_page` and `landing_page` rows are eligible. One toggle
    covers both, which is why three toggles govern four kinds of destination.
  </Property>
  <Property name="excludePostIds" type="post ids">
    Individual posts you never want linked to, whatever the toggles say.
  </Property>
</PropertyList>

Turning a toggle off removes that kind of destination from the inventory
entirely, so the four-row table above describes the largest set of destinations
available to you rather than a fixed one.

Density is not a number you set. Blogged follows a balanced policy: a soft
target band per thousand words, each destination used once, and an article left
short of target rather than carrying a link that does not belong in it.
