How I Rebuilt Internal Linking for a 100+ Article Website?

I recently worked on a website with more than 100 published articles.

The site had been around for years.

It was originally built on WordPress. Later, it was migrated to Astro.

The migration itself worked fine.

The pages loaded fast. The URLs were mostly preserved. The new site was much cleaner.

Then I started checking the internal links.

That part was messy.

Some articles had almost no links pointing to them.

Some links still went through old WordPress URLs.

A few links were pointing to image files instead of actual articles.

There were also some very strange links left behind by old automatic linking rules.

So I decided to clean the whole thing up.

Not by adding random links everywhere.

I wanted every link to make sense for the person reading the page.

Note: I have removed the client name, domain, article titles, URLs, and other identifying details from this post.

Why I checked internal linking?

The website had a large amount of old content.

Some articles were important.

Others were very specific.

But the way they were connected did not really reflect that.

A few pages had a lot of links pointing to them.

Many others had almost none.

That made me wonder how much of the old WordPress structure was still affecting the new site.

So I exported the article relationships and started checking them one by one.

I was not looking for a magic number.

I just wanted to answer a few simple questions.

  • Can every important article be reached from another useful page?
  • Are internal links pointing directly to the current URL?
  • Do the links make sense in the sentence where they appear?
  • Are old WordPress links still being used?
  • Are related articles actually related?
  • Are important pages buried while less useful pages get linked everywhere?

The answer to several of those questions was yes.

What I found?

There were a few different problems.

Some articles were almost isolated

More than 20 articles had no meaningful editorial links pointing to them.

Many more had only one or two.

The pages were technically reachable through category pages and other site navigation.

But they were barely connected to the rest of the actual content.

I did not want to solve this by forcing five links into every article.

That would just create another problem.

Old WordPress URLs were still being used

Some articles linked to old slugs.

The old URL would redirect to the new URL.

So the link still worked.

But it looked like this:

Article

Old WordPress URL

301 redirect

Current Astro URL

There was no reason to keep doing that.

I changed those links to point directly to the current page.

Article

Current Astro URL

Simple.

This was one of the stranger problems.

The anchor text looked like it linked to another article.

But the actual URL pointed to an old WordPress image upload.

Something like:

"Read about company registration"

/wp-content/uploads/.../company-registration.jpg

The reader expected an article.

They got an image.

Those were replaced with the real article URLs.

Old automatic linking created weird connections

The old site had some automatic keyword linking.

That sounds useful until the same word means different things in different contexts.

For example, a word describing work or burden in one article could link to employment law.

A general word related to harassment could link to a completely different legal topic.

The link technically matched the word.

It did not match the meaning.

That was the important difference.

I removed those links.

There were also hand-written or automatically added recommendations that had very little connection to the article.

A reader could be learning about one legal process and suddenly get a recommendation for something completely unrelated.

Those links were not helping anyone.

I replaced them with pages that were actually useful as the next step.

I stopped thinking about silos

At first, it is easy to think about internal linking in categories.

Family content should link to family content.

Business content should link to business content.

Civil content should stay inside civil content.

That sounds organized.

Real users do not behave like that.

A person dealing with one legal issue often needs information from another area.

Someone going through a family dispute may also need information about property.

Someone living abroad may need a power of attorney.

Someone dealing with unpaid money may need information about both debt recovery and banking rules.

So I stopped treating categories like walls.

I started thinking about the next question the reader would probably ask.

That changed the whole structure.

The rule I used

The rule became very simple.

Add a link when the destination helps answer the next question the reader is likely to have.

That could mean:

  • a document they need first
  • another process that comes next
  • a consequence of the current issue
  • an alternative route
  • a related problem they may also need to solve

I did not use fixed anchor text ratios.

I did not set a rule like “five links per 1,000 words.”

I did not force links into the first 300 words.

If a link made sense, I used it.

If it did not, I left it out.

The two-part system

I ended up using two types of internal links.

1. Links inside the article

These are the most natural ones.

If a paragraph mentions another process and the reader may need more detail, I link the relevant words.

For example:

A user is reading about Process A.

The article explains that Document B is required first.

"Document B" links to the complete guide for Document B.

The link belongs there because the reader may actually need it.

I also added three related resources near the end of each article.

I did not use random posts.

I did not simply show the latest three posts.

Each article was mapped to three useful next steps.

The idea looked like this:

[ Current Article ]
   ├── Prerequisite ───────────────> [ Useful Guide ]
   ├── Next Legal Step ────────────> [ Useful Guide ]
   └── Related Problem / Route ────> [ Useful Guide ]

This gave every article a small, predictable set of related pages.

It also helped reduce isolated content without filling the article body with unnecessary links. Right before the author bio, I also paired this setup with a Google Preferred Sources callout card so interested readers could easily follow the site in Google Search.

I did not edit more than 100 articles manually.

The content was stored as structured data, so I wrote scripts to audit the links.

Before changing anything, I made a full backup.

Then I checked for:

  • old redirecting URLs
  • absolute internal URLs
  • image URLs used as article links
  • raw URLs shown as anchor text
  • broken links
  • strange automatic links
  • mismatched recommendations
  • links to pages that no longer existed

I fixed the safe ones programmatically.

For anything that could change the meaning of the article, I checked it manually.

That part was important.

A script can tell me that a URL redirects.

It cannot always tell me whether two legal topics should be connected.

Before and after

The structure changed quite a bit.

Before:

[ Popular Article A ] ──────> [ Popular Articles B & C ]

[ Articles D & E ]

Isolated Pages (Zero Contextual Links):
[ Article F ]   [ Article G ]   [ Article H ]

Redirect Chains:
Old WordPress Slug ──301 Redirect──> Current Canonical URL

After:

[ Main Guide ] ─────────> [ Related Guide ] ──> [ Next Step ]

      └──> [ Prerequisite ] ──> [ Supporting Guide ]

[ Niche Article ] ┘

[ Related Article ] ──── [ Context Article ]

Direct Internal Links:
Article Link ───────────> Current Canonical URL

The goal was not to make every page equally important.

That would not make sense either.

Some pages should receive more internal attention than others.

The goal was to make sure the site structure reflected what people actually need.

This was probably the most useful part.

Most internal linking tools focus on outgoing links.

I cared more about incoming links.

For every article, I wanted to know:

Article
Incoming contextual links
Incoming related-resource links
Total incoming links
Pages linking to it

That made it easy to spot important pages that were still buried.

It also showed me pages that were already receiving enough attention.

I left those alone.

I did not try to push every page above a number

This is something I changed my mind about while working on the site.

It is tempting to say:

Every article needs at least five internal links.

But why?

A very specific article may only need two.

A major guide may naturally receive 15 or 20.

Those numbers alone do not tell me whether the structure is good.

So I grouped pages instead.

Type What I did
Important but underlinked Look for real places where they should be referenced
Important and already well linked Leave them alone
Niche and underlinked Usually fine
Very prominent pages Check that the prominence still makes sense

This worked better than chasing a sitewide minimum.

What changed?

After the cleanup:

  • all published articles had at least one meaningful route from other content
  • old redirect hops were removed from internal article links
  • image links were corrected
  • strange automatic links were removed
  • mismatched “Also Read” links were replaced
  • hundreds of article relationships were reviewed or added
  • related resources became predictable instead of random
  • the link structure became much easier to audit

The biggest improvement was not a number.

The site finally made sense when I followed the links myself.

Did rankings improve?

I do not know yet.

And I do not want to pretend that I do.

The site was also recently migrated from WordPress to Astro.

That means there are several changes happening at the same time.

Google also needs time to crawl the updated pages and understand the new structure.

So I am not going to claim:

“Internal linking increased traffic by 300%.”

I do not have that result.

For now, I am watching:

  • Google impressions
  • clicks
  • important query positions
  • indexing
  • pages that were previously underlinked
  • which pages Google recrawls
  • whether important sections start getting more visibility

I will update this post later if the data becomes interesting.

What I learned?

A few things stood out to me.

The difficult part was deciding which links should exist.

Writing a script was easy.

Understanding the relationship between the pages took more time.

Categories are useful, but users do not care about your silos

A user follows a problem.

They do not care whether the next article lives in another category.

If the next page helps them, the link makes sense.

Old migrations leave small problems everywhere

The redirects worked.

The pages loaded.

Nothing looked broken.

But old links, image paths, and automatic WordPress rules were still hiding inside the content.

A migration can be technically complete while the old content still carries years of baggage.

“Latest posts” is easy to build.

It is not always useful.

I would rather show three pages that genuinely continue the reader’s journey.

Sometimes the right fix was adding a link.

Sometimes it was deleting one.

That was probably the biggest lesson.

What would I do differently next time?

I would audit the internal content graph before the migration.

That would make it easier to separate old structural problems from migration problems.

I would also define the important content journeys earlier.

Something like:

Main topic

Core guide

Prerequisite

Next step

Related problem

Then I would use that map while moving the content.

It would save a lot of cleanup later.

For now

The internal linking work is mostly finished.

I am not going to keep changing it every week.

The next step is to let the structure settle and work on the actual content.

Some articles still need updates.

Some need better sources.

Some are already good and should probably be left alone.

That is where I am focusing next.

I will come back to the internal linking data once there is enough search data to compare before and after.

Want my posts to show up more often on Google?

One click and Google will surface this site in your Top Stories.

Add as preferred source
Suraj Katwal
Written by

Suraj Katwal

Digital marketer, data enthusiast, and developer based in Melbourne, originally from Nepal. I build web platforms, Flutter apps, and digital marketing campaigns. On the data side, I work with SQL and Python while growing into dbt and data pipeline tools.