• KodeRian
    KodeRian — A place to share tips, tricks, SEO insights, coding guides, and Blogger tutorials covering HTML, CSS, JavaScript, and AdSense.

    How to Replace “Next/Previous” with Post Titles in Blogger (jQuery & Pure JavaScript)

    Turn Blogger’s Next/Previous into clickable post titles with jQuery or pure JavaScript. Copy-paste code, styles, tips, FAQs, and fixes. UX and SEO win
    Replace “Next/Previous” with Real Post Titles in Blogger (Complete Step-by-Step Guide)

    By default, Blogger shows pretty bare “Next” and “Previous” (or “Older” and “Newer”) links at the bottom of your posts. They work, sure, but they don’t exactly sell the click. Swapping those generic labels for the actual post titles gives readers more context and a reason to keep reading—better UX, longer session duration, and a not-so-small boost to internal linking, which helps with SEO.

    In this expanded tutorial, you’ll learn two clean ways to implement title-based navigation in Blogger:

    • Option A (jQuery): quick to ship if your template already loads jQuery.
    • Option B (Pure JavaScript): dependency-free and lightweight, great for modern templates.

    Both approaches produce the same result: navigation cards showing the previous and next post titles (and optionally thumbnails), wrapped in a minimal, responsive style. The tutorial is copy-paste friendly, and each step includes exactly where to place the code in the Blogger theme editor. We’ll finish with FAQs, troubleshooting, and style tweaks so it sits perfectly in your design system.


    Why Replace “Next/Previous” with Post Titles?

    • Clarity for readers: A title tells them what’s next, not just that something is next.
    • More internal clicks: Clear, descriptive links increase the chance readers explore more.
    • SEO benefits: Strong internal linking helps search engines understand topic clusters and content depth.
    • Design consistency: Styled navigation cards look more intentional than plain text links.

    We’ll keep the spirit of Blogger’s pager intact, but make it feel like part of your site—not a leftover.


    What We’re Building

    We’ll add a small <b:includable> block called nav-post, then inject the previous/next titles into it using either jQuery or pure JS. You’ll also get a simple CSS layout that’s responsive and clean.

    If you want thumbnails in the nav, we’ve included optional code for that, too.


    Before You Start

    • Backup your theme: Blogger → Theme → ⋮ → Backup.
    • Know your widget ID: Most templates use Blog1 for the main posts widget. If yours differs, adjust IDs accordingly in the code.
    • jQuery or Not? If your template doesn’t include jQuery and you don’t want to add it, skip to the Pure JavaScript option.

    Optional: Load jQuery (only if using Option A)

    Place this right before </head> if your theme doesn’t already include jQuery.

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js" async="async"></script>
    

    Create the Navigation Markup (Shared for Both Methods)

    Add a new includable that renders the navigation wrapper. Insert it below the main includable inside the Blog1 widget.

    Step 1 — Add nav-post includable

    In Theme → Edit HTML, find the Blog1 widget. Right after <b:includable id='main'>, paste this block:

    <b:includable id='nav-post'>
      <div class='nav-post'>
        <div class='pagination-left'>
          <b:if cond='data:newerPageUrl'>
            <a class='blog-pager-newer-link'
               expr:href='data:newerPageUrl'
               expr:id='data:widget.instanceId + &quot;_blog-pager-newer-link&quot;'
               expr:title='data:newerPageTitle' />
          <b:else />
            <a href='javascript:;' title='No more post'>
              <div class='pagination-header'>
                <span class='pagination-icon'>
                  <svg viewBox='0 0 24 24'><path d='M15.41,16.58L10.83,12L15.41,7.41L14,6L8,12L14,18L15.41,16.58Z' fill='currentColor'/></svg>
                </span>
                <span class='pagination-title'>Previous Post</span>
              </div>
              <div class='pagination-content'><span class='pagination-title'>This Is The Current Newest Page</span></div>
            </a>
          </b:if>
        </div>
    
        <div class='pagination-right'>
          <b:if cond='data:olderPageUrl'>
            <a class='blog-pager-older-link'
               expr:href='data:olderPageUrl'
               expr:id='data:widget.instanceId + &quot;_blog-pager-older-link&quot;'
               expr:title='data:olderPageTitle' />
          <b:else />
            <a href='javascript:;' title='No more post'>
              <div class='pagination-header'>
                <span class='pagination-title'>Next Post</span>
                <span class='pagination-icon'>
                  <svg viewBox='0 0 24 24'><path d='M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z' fill='currentColor'/></svg>
                </span>
              </div>
              <div class='pagination-content'><span class='pagination-title'>This Is The Current Newest Page</span></div>
            </a>
          </b:if>
        </div>
      </div>
    </b:includable>
    

    Step 2 — Call the navigation only on post pages

    Still inside the Blog1 widget, find:

    <b:includable id='post' var='post'>
    

    Then add the include at the bottom of that block:

    <b:if cond='data:view.isPost'>
      <b:include name='nav-post'/>
    </b:if>
    

    Final shape of the includable (trimmed for clarity):

    <b:includable id='post' var='post'>
      <article class='post hentry'>...</article>
      <b:if cond='data:view.isPost'>
        <b:include name='nav-post'/>
      </b:if>
    </b:includable>
    

    Add the Styles (Shared for Both Methods)

    Paste this CSS above </b:skin> (or inside your theme’s stylesheet). It creates a two-column layout—previous on the left, next on the right—with subtle hover states.

    .nav-post{display:flex;flex-flow:row nowrap;margin:40px -20px;justify-content:space-between}
    .nav-post > *{display:flex;flex:0 0 50%;max-width:50%;padding:0 20px}
    .nav-post a{display:flex;flex:1;flex-flow:column nowrap;color:inherit;text-decoration:none}
    .nav-post .pagination-right .pagination-header{margin-left:auto}
    .nav-post .pagination-header{display:flex;align-items:center;font-size:12px;font-weight:700;margin-bottom:15px;letter-spacing:.08em;text-transform:uppercase;color:#667085}
    .nav-post .pagination-content{display:flex;align-items:center;font-size:15px;font-weight:700;line-height:1.5}
    .nav-post .pagination-right .pagination-content{flex-flow:row-reverse;text-align:right}
    .nav-post .pagination-content .pagination-title{color:inherit;text-decoration-line:underline;text-decoration-color:transparent;transition:all .25s cubic-bezier(.32,.74,.57,1)}
    .nav-post .pagination-content .pagination-title:hover{color:#005af0;text-decoration-color:currentColor}
    .nav-post .pagination-icon{display:inline-flex}
    .nav-post .pagination-thumb{display:flex;flex-shrink:0;margin-right:12px;width:50px;height:50px}
    .nav-post .pagination-right .pagination-thumb{margin-right:0;margin-left:12px}
    .nav-post .pagination-thumb img{width:100%;height:100%;border-radius:50%;object-fit:cover}
    @media (max-width:480px){
      .nav-post > *:not(:last-child){border-right:thin solid rgba(0,0,0,.07)}
      .nav-post .pagination-thumb{display:none}
    }
    

    Pro tip: If your template supports dark mode via a class (e.g., .nightmode on <body>), you can darken .pagination-header text or add subtle borders to fit your palette.


    Option A — jQuery Method (quick if you already load jQuery)

    This approach fetches the neighboring post pages and reads their titles (and optionally thumbnails), then injects them into the navigation.

    Step 3A — Insert the jQuery script (right before </body>)

    <b:if cond='data:view.isPost'>
    <script>/*<![CDATA[*/
    (function ($) {
      var next = 'Next', prev = 'Previous';
      var newerLink = $('a.blog-pager-newer-link');
      var olderLink = $('a.blog-pager-older-link');
    
      if (newerLink.length && newerLink.attr('href')) {
        $.get(newerLink.attr('href'), function (data) {
          var title = $(data).find('.post-title').first().text();
          var header = "<div class='pagination-header'><span class='pagination-icon'><svg viewBox='0 0 24 24'><path fill='currentColor' d='M15.41,16.58L10.83,12L15.41,7.41L14,6L8,12L14,18L15.41,16.58Z'></path></svg></span><span class='pagination-title'>"+prev+"</span></div>";
          var body = "<div class='pagination-content'><span class='pagination-title'>"+ title +"</span></div>";
          newerLink.html(header + body);
        }, 'html');
      }
    
      if (olderLink.length && olderLink.attr('href')) {
        $.get(olderLink.attr('href'), function (data2) {
          var title2 = $(data2).find('.post-title').first().text();
          var header2 = "<div class='pagination-header'><span class='pagination-title'>"+next+"</span><span class='pagination-icon'><svg viewBox='0 0 24 24'><path fill='currentColor' d='M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z'></path></svg></span></div>";
          var body2 = "<div class='pagination-content'><span class='pagination-title'>"+ title2 +"</span></div>";
          olderLink.html(header2 + body2);
        }, 'html');
      }
    })(jQuery);
    /*]]>*/</script>
    </b:if>
    

    Optional — Add thumbnails with jQuery

    To show the first image from each neighboring post, use this variant instead (still right before </body>):

    <script>/*<![CDATA[*/
    (function ($) {
      var next = 'Next', prev = 'Previous';
      var newerLink = $('a.blog-pager-newer-link'); 
      var olderLink = $('a.blog-pager-older-link');
    
      if (newerLink.length && newerLink.attr('href')) {
        $.get(newerLink.attr('href'), function (data) {
          var $d = $(data), title = $d.find('.post-title').first().text();
          var img = $d.find('.post-body img:first').attr('src');
          if (img) { img = img.replace(/.*?:\/\//, '//').replace('s1600', 's386'); }
          var header = "<div class='pagination-header'><span class='pagination-icon'><svg viewBox='0 0 24 24'><path fill='currentColor' d='M15.41,16.58L10.83,12L15.41,7.41L14,6L8,12L14,18L15.41,16.58Z'></path></svg></span><span class='pagination-title'>"+prev+"</span></div>";
          var thumb = img ? "<span class='pagination-thumb'><img alt='"+ title +"' src='"+ img +"' width='386' height='170' /></span>" : "";
          var body = "<div class='pagination-content'>"+ thumb +"<span class='pagination-title'>"+ title +"</span></div>";
          newerLink.html(header + body);
        }, 'html');
      }
    
      if (olderLink.length && olderLink.attr('href')) {
        $.get(olderLink.attr('href'), function (data2) {
          var $d2 = $(data2), title2 = $d2.find('.post-title').first().text();
          var img2 = $d2.find('.post-body img:first').attr('src');
          if (img2) { img2 = img2.replace(/.*?:\/\//, '//').replace('s1600', 's386'); }
          var header2 = "<div class='pagination-header'><span class='pagination-title'>"+next+"</span><span class='pagination-icon'><svg viewBox='0 0 24 24'><path fill='currentColor' d='M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z'></path></svg></span></div>";
          var thumb2 = img2 ? "<span class='pagination-thumb'><img alt='"+ title2 +"' src='"+ img2 +"' width='386' height='170' /></span>" : "";
          var body2 = "<div class='pagination-content'>"+ thumb2 +"<span class='pagination-title'>"+ title2 +"</span></div>";
          olderLink.html(header2 + body2);
        }, 'html');
      }
    })(jQuery);
    /*]]>*/</script>
    

    Option B — Pure JavaScript (no jQuery)

    This method uses Blogger’s JSON feed to fetch the neighboring post’s metadata (title, thumbnail) and then injects it into the pager links.

    Step 3B — Insert the pure JS script (right before </body>)

    <b:if cond='data:view.isPost'>
    <script>/*<![CDATA[*/
    var next = 'Next', prev = 'Previous';
    
    (function () {
      if (!/.+\.html(\?m=1)?$/.test(location.href)) return;
    
      var olderLink = document.getElementById('Blog1_blog-pager-older-link');
      if (olderLink) {
        getPageTitle(olderLink, setOlderPageTitle);
      }
    
      var newerLink = document.getElementById('Blog1_blog-pager-newer-link');
      if (newerLink) {
        getPageTitle(newerLink, setNewerPageTitle);
      }
    
      function setOlderPageTitle(data) {
        injectTitle(data, olderLink, next, true);   // next = moving forward in time
      }
      function setNewerPageTitle(data) {
        injectTitle(data, newerLink, prev, false);  // prev = moving backward in time
      }
    
      function injectTitle(data, linkEl, label, isNext) {
        var title = (data && data.feed && data.feed.entry && data.feed.entry.length)
          ? data.feed.entry[0].title.$t : '';
    
        if (!title || !linkEl) return;
    
        var leftIcon = isNext
          ? "<span class='pagination-title'>"+label+"</span><span class='pagination-icon'><svg viewBox='0 0 24 24'><path fill='currentColor' d='M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z' /></svg></span>"
          : "<span class='pagination-icon'><svg viewBox='0 0 24 24'><path fill='currentColor' d='M15.41,16.58L10.83,12L15.41,7.41L14,6L8,12L14,18L15.41,16.58Z' /></svg></span><span class='pagination-title'>"+label+"</span>";
    
        var header = "<div class='pagination-header'>"+ leftIcon +"</div>";
        var body   = "<div class='pagination-content'><span class='pagination-title'>"+ title +"</span></div>";
        linkEl.innerHTML = header + body;
      }
    
      function getPageTitle(pageLink, callback) {
        var href = pageLink.getAttribute('href');
        if (!href) return;
        var pathname = href.replace(location.protocol + '//' + location.hostname, '');
        var script = document.createElement('script');
        script.src = '/feeds/posts/summary?alt=json-in-script&max-results=1&redirect=false&path=' + pathname + '&callback=' + callback.name;
        document.body.appendChild(script);
      }
    })();
    /*]]>*/</script>
    </b:if>
    

    Optional — Pure JS with thumbnails

    <script>/*<![CDATA[*/
    (function(){
      if (!/.+\.html(\?m=1)?$/.test(location.href)) return;
    
      var older = document.getElementById('Blog1_blog-pager-older-link');
      var newer = document.getElementById('Blog1_blog-pager-newer-link');
    
      if (older) getMeta(older, renderOlder);
      if (newer) getMeta(newer, renderNewer);
    
      function renderOlder(data){ renderInto(older, data, 'Next', true); }
      function renderNewer(data){ renderInto(newer, data, 'Previous', false); }
    
      function renderInto(el, data, label, isNext){
        if (!el || !data || !data.feed || !data.feed.entry || !data.feed.entry.length) return;
        var entry = data.feed.entry[0];
        var title = entry.title.$t || '';
        var thumb = entry.media$thumbnail ? entry.media$thumbnail.url : '';
        var thumbSpan = thumb ? "<span class='pagination-thumb'><img alt='"+ title +"' src='"+ thumb +"' /></span>" : '';
    
        var header = isNext
          ? "<div class='pagination-header'><span class='pagination-title'>"+label+"</span><span class='pagination-icon'><svg viewBox='0 0 24 24'><path fill='currentColor' d='M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z' /></svg></span></div>"
          : "<div class='pagination-header'><span class='pagination-icon'><svg viewBox='0 0 24 24'><path fill='currentColor' d='M15.41,16.58L10.83,12L15.41,7.41L14,6L8,12L14,18L15.41,16.58Z' /></svg></span><span class='pagination-title'>"+label+"</span></div>";
    
        var body = "<div class='pagination-content'>"+ (isNext ? "" : "") + thumbSpan + "<span class='pagination-title'>"+ title +"</span></div>";
        el.innerHTML = header + body;
      }
    
      function getMeta(pageLink, cb){
        var href = pageLink.getAttribute('href') || '';
        var path = href.replace(location.protocol + '//' + location.hostname, '');
        var s = document.createElement('script');
        s.src = '/feeds/posts/summary?alt=json-in-script&max-results=1&redirect=false&path='+ encodeURIComponent(path) +'&callback='+ cb.name;
        document.body.appendChild(s);
      }
    })();
    /*]]>*/</script>
    

    Style & UX Tips

    • Labels: If your audience expects “Older/Newer,” just replace the next/prev variables accordingly.
    • Directionality: In many templates, “older” is the right-side link. Keep the arrow icons and text aligned with that mental model.
    • Thumbnails: They’re optional but effective for click-through. If your posts lack images, skip the thumb block.
    • Mobile polish: The CSS hides thumbnails on very small screens to keep things tidy. Adjust the breakpoint if needed.
    • Dark Mode: If you use a .nightmode class on <body>, override colors to fit (e.g., lighten .pagination-header, tweak link hover color).
    • Scrollbar consistency: If your site uses off-canvas panels or long sidebars, consider a customize scrollbar Blogger style from a Blogger CSS scrollbar snippet so everything feels cohesive. (See our custom scrollbar tutorial linked above.)

    Troubleshooting

    • Titles not showing: Ensure the selector paths match your theme. For jQuery fetch, we’re targeting .post-title inside the fetched HTML; some templates use different class names.
    • Links not found: Your pager anchors may render with different IDs if you’ve renamed the widget (Blog2, etc.). Update the IDs in scripts (Blog1_blog-pager-older-link / Blog1_blog-pager-newer-link).
    • Cross-domain issues: The jQuery version loads full neighboring pages as HTML (same domain → OK). If you use a custom domain + preview frames, test on the live URL, not preview.
    • Feed returns nothing: The pure JS version uses /feeds/posts/summary with a path parameter. If a post is draft or private, you won’t get a title.
    • Performance concerns: The jQuery method makes 1–2 small GET requests. If you want fewer calls, prefer the pure JS feed approach which returns just metadata.
    • Thumbnails broken: If your images use different size tokens (e.g., s72-c vs s1600), adjust the replacement to a size your layout expects (e.g., s386).

    FAQ

    1) Which method is better for SEO?

    Both produce the same visible HTML for users. The pure JS method is a bit lighter and avoids loading whole pages in the background. In practice, either is fine—choose based on your template and comfort.

    2) Can I use custom text like “Read Next”?

    Yes. Just change the next and prev variables or the inline strings in the SVG header blocks.

    3) How do I add rel attributes?

    You can add rel="prev" and rel="next" to the anchor tags in nav-post. It won’t hurt and can help hint relationships.

    4) Will this work with mobile views (?m=1)?

    Yes. The pure JS example even includes a regex that accounts for ?m=1 in the URL. Test both desktop and mobile to be sure your theme’s structure matches the selectors.

    5) Can I include excerpts under the titles?

    You can fetch snippets the same way you fetch titles (either from the page HTML via jQuery or from the feed summary). Be mindful of layout length on mobile.

    6) Does customizing this break my theme updates?

    If you update/replace your theme later, you’ll need to re-add these customizations. Keep a copy of the code in a note for quick re-apply.


    Copy-Paste Reference (Quick Blocks)

    Navigation includable

    <b:includable id='nav-post'> ... </b:includable>
    

    Include on post pages

    <b:if cond='data:view.isPost'><b:include name='nav-post'/></b:if>
    

    Core CSS

    .nav-post{display:flex;flex-flow:row nowrap;margin:40px -20px;justify-content:space-between} /* ...see full block above... */
    

    Pick one script

    • jQuery version (HTML fetch)
    • Pure JS version (JSON feed)

    Conclusion

    Small change, big payoff. Replacing “Next/Previous” with real post titles turns a generic pager into a compelling nudge to keep reading. It’s a clean, UX-friendly internal link that signals content relationships to readers and search engines alike. Start with the minimal title-only version, and if your posts have strong images, try the thumbnail variant for an extra lift.

    Want your interface to feel even more intentional? Pair this with a subtle visual system—consistent hover states, a matching Blogger CSS scrollbar (yep, you can customize scrollbar Blogger-style with pure CSS), and a readable typographic scale. Your blog will look and feel like it was designed as a whole, not assembled from parts.

    Found this helpful? Please bookmark the guide, share it with another Blogger creator, and subscribe so you don’t miss future tutorials.

    Post a Comment

    Comment Guidelines

    Please keep your comments relevant to the topic (Blogger, SEO, coding, etc.).

    Be respectful — no spam, offensive language, or personal attacks.

    You may share suggestions, bug reports, or tutorial requests.

    External links are allowed only if they are truly helpful and not for promotion.

    Feedback will be reviewed, and I will try to reply as soon as possible.

    By commenting here, you help improve KodeRian and keep the discussion useful for everyone.