Massblogger

Internal Links API

Automatically add internal links to your content based on keywords you configure. No need to read this if you are using WordPress It works out of the box.

Overview

Internal links are essential for SEO and user navigation. With the Internal Links API, you can:

  • Define keyword-to-URL mappings in your MassBlogger dashboard
  • Fetch these mappings via API when rendering your content
  • Automatically replace keywords with links in your blog posts
  • Maintain consistent internal linking across all your content

Endpoint

GET/api/internal-links

Returns all internal links configured for your website.

Query Parameters

apiKeyRequiredYour website API key

Example Request

GET https://www.massblogger.com/api/internal-links?apiKey=YOUR_API_KEY

Response Format

The API returns an array of keyword-URL pairs:

contact us/contact
pricing/pricing
best practices/blog/best-practices
getting started/docs/getting-started
keywordstringThe keyword to search for in your content
urlstringThe URL to link to when the keyword is found

Usage Examples

Next.js (App Router)

// lib/internal-links.js
const API_KEY = process.env.MASSBLOGGER_API_KEY;
const API_URL = 'https://www.massblogger.com';

export async function getInternalLinks() {
  const res = await fetch(
    `${API_URL}/api/internal-links?apiKey=${API_KEY}`,
    { next: { revalidate: 3600 } } // Cache for 1 hour
  );
  return res.json();
}

export function applyInternalLinks(content, links) {
  let result = content;
  
  links.forEach(({ keyword, url }) => {
    // Match whole words only, case-insensitive
    const regex = new RegExp('\\b' + keyword + '\\b', 'gi');
    
    // Only replace first occurrence to avoid over-linking
    let replaced = false;
    result = result.replace(regex, (match) => {
      if (replaced) return match;
      replaced = true;
      return '<a href="' + url + '" class="internal-link">' + match + '</a>';
    });
  });
  
  return result;
}

Usage in a blog post page:

// app/blog/[slug]/page.js
import { getInternalLinks, applyInternalLinks } from '@/lib/internal-links';

export default async function BlogPost({ params }) {
  const [post, links] = await Promise.all([
    getPost(params.slug),
    getInternalLinks()
  ]);
  
  const contentWithLinks = applyInternalLinks(post.content, links);
  
  return (
    <article>
      <h1>{post.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: contentWithLinks }} />
    </article>
  );
}

React (Client-side)

import { useState, useEffect } from 'react';

function useInternalLinks(apiKey) {
  const [links, setLinks] = useState([]);
  
  useEffect(() => {
    fetch('https://www.massblogger.com/api/internal-links?apiKey=' + apiKey)
      .then(res => res.json())
      .then(setLinks)
      .catch(console.error);
  }, [apiKey]);
  
  return links;
}

function applyInternalLinks(content, links) {
  let result = content;
  
  links.forEach(({ keyword, url }) => {
    const regex = new RegExp('\\b' + keyword + '\\b', 'gi');
    let replaced = false;
    result = result.replace(regex, (match) => {
      if (replaced) return match;
      replaced = true;
      return '<a href="' + url + '">' + match + '</a>';
    });
  });
  
  return result;
}

// Usage in component
function BlogPost({ post }) {
  const links = useInternalLinks('your_api_key');
  const content = applyInternalLinks(post.content, links);
  
  return <div dangerouslySetInnerHTML={{ __html: content }} />;
}

Vanilla JavaScript

const API_KEY = 'your_api_key';

async function fetchInternalLinks() {
  const response = await fetch(
    'https://www.massblogger.com/api/internal-links?apiKey=' + API_KEY
  );
  return response.json();
}

function applyInternalLinks(content, links) {
  let result = content;
  
  links.forEach(({ keyword, url }) => {
    // Create regex that matches whole words only
    const regex = new RegExp('\\b' + keyword + '\\b', 'gi');
    
    // Replace only first occurrence
    let replaced = false;
    result = result.replace(regex, function(match) {
      if (replaced) return match;
      replaced = true;
      return '<a href="' + url + '">' + match + '</a>';
    });
  });
  
  return result;
}

// Usage
document.addEventListener('DOMContentLoaded', async () => {
  const links = await fetchInternalLinks();
  const article = document.querySelector('.article-content');
  
  if (article) {
    article.innerHTML = applyInternalLinks(article.innerHTML, links);
  }
});

PHP

<?php
$api_key = 'your_api_key';

function getInternalLinks($api_key) {
    $url = "https://www.massblogger.com/api/internal-links?apiKey=" . $api_key;
    $response = file_get_contents($url);
    return json_decode($response, true);
}

function applyInternalLinks($content, $links) {
    foreach ($links as $link) {
        $keyword = $link['keyword'];
        $url = $link['url'];
        
        // Match whole words only, case-insensitive
        $pattern = '/\b(' . preg_quote($keyword, '/') . ')\b/i';
        
        // Replace only first occurrence
        $content = preg_replace($pattern, '<a href="' . htmlspecialchars($url) . '">$1</a>', $content, 1);
    }
    
    return $content;
}

// Usage
$links = getInternalLinks($api_key);
$post_content = get_the_content(); // Your content source
$content_with_links = applyInternalLinks($post_content, $links);

echo $content_with_links;
?>

Best Practices

  • Cache responses: Internal links don't change often. Cache the API response for at least 1 hour to reduce API calls.
  • Limit replacements: Only replace the first occurrence of each keyword to avoid over-linking, which can hurt SEO and readability.
  • Use whole word matching: Use word boundaries in your regex to avoid matching partial words.
  • Process server-side: For SEO benefits, apply internal links on the server before sending HTML to the client.
  • Avoid nested links: Be careful not to insert links inside existing anchor tags. Consider parsing HTML properly for complex content.
  • Order by length: Process longer keywords first to avoid partial matches (e.g., "getting started guide" before "getting started").

Need help? Contact us at support@massblogger.com