블로그스팟(Blogger)은 무료이면서도 강력한 블로그 플랫폼이지만, 기본 기능만으로는 “관련 글 자동 연결”이 제공되지 않습니다. 이 글에서는 구글 SEO를 고려한 내부 링크 자동 생성 방법을 소개합니다.
왜 관련 글 자동 생성이 중요한가요?
- 내부 링크 강화로 SEO 최적화
- 방문자 이탈률 감소 → 블로그 체류 시간 증가
- 콘텐츠 탐색 흐름 유도로 사용자 경험 향상
적용 방법 요약
<data:post.body/> 바로 아래에 관련 글 HTML 코드 삽입<div class='related-posts' role='navigation'>
<h2>관련 글</h2>
<script id='related-posts-site-json' type='application/json'>
{
"debug": false,
"homepageUrl": "<data:blog.homepageUrl/>",
"params": "orderby=updated",
"url": "<data:post.url/>",
"title": "<data:post.title.jsonEscaped/>",
"snippet": "<data:post.snippets.short.jsonEscaped/>",
"useSnippet": true,
"useLastPosts": true,
"min": -1,
"max": 5,
"prefix": "<ul class='related-post'>",
"sufix": "</ul>",
"dummy": "<li>&nbsp;</li>",
"format": "<li><a href='${url}'>${title}</a></li>",
"labels": [<b:loop index='i' values='data:post.labels' var='label'><b:if cond='data:i != 0'>,</b:if>"<data:label.name.jsonEscaped/>"</b:loop>]
}
</script>
</div>.related-posts h2 {
font-size: 1.4em;
margin-bottom: 20px;
font-weight: bold;
color: #333;
border-bottom: 2px solid #ff6b6b;
padding-bottom: 8px;
}
/* 번호 있는 리스트 스타일 */
.related-posts ul.related-post {
counter-reset: related-counter;
list-style: none;
padding-left: 0;
display: flex;
flex-direction: column;
gap: 10px;
}
.related-posts ul.related-post li {
counter-increment: related-counter;
background-color: #fff;
border: 1px solid #eee;
border-radius: 8px;
padding: 12px 16px 12px 48px; /* 왼쪽 여백 추가 */
position: relative;
transition: 0.2s ease-in-out;
font-size: 1em;
}
.related-posts ul.related-post li::before {
content: counter(related-counter) ".";
position: absolute;
left: 16px;
top: 50%;
transform: translateY(-50%);
font-weight: bold;
color: #ff6b6b;
font-size: 1.1em;
}
.related-posts ul.related-post li:hover {
background-color: #ffefef;
border-color: #ff6b6b;
transform: translateY(-2px);
}
.related-posts ul.related-post li a {
text-decoration: none;
color: #333;
font-weight: 500;
}
.related-posts ul.related-post li a:hover {
color: #e60000;
}
</body> 위에 FeedRelatedPosts.js 스크립트 삽입
<script>
//<![CDATA[
/*! FeedRelatedPosts.js v2.2 | MIT License | https://github.com/k08045kk/FeedRelatedPosts.js/blob/master/LICENSE */ !function(e,t){if(!e.FeedRelatedPosts){let a=e.FeedRelatedPosts||function(){},l=a.pages=a.pages||[],s=a.labels=a.labels||[];for(let r=0;r<2;r++){let n=0==r?a.siteJsonQuery||"#related-posts-site-json":a.pageJsonQuery||"#related-posts-page-json",i=document.querySelector(n);try{let p=i&&JSON.parse(i.textContent)||{};for(let o in Array.prototype.push.apply(l,p.pages||[]),Array.prototype.push.apply(s,p.labels||[]),p)p.hasOwnProperty(o)&&(a[o]=p[o])}catch(u){}}a.pages=!0===a.pushPages?l:a.pages,a.labels=!0===a.pushLabels?s:a.labels,e.FeedRelatedPosts=t(a,document),!1!==a.run&&e.FeedRelatedPosts.init()}}(this,function(e,t){"use strict";let a=function(e){let a=t.createElement("script");a.type="text/javascript",a.async=!0,a.src=e;let l=t.getElementsByTagName("script")[0];l.parentNode.insertBefore(a,l)},l=function(){let e=/&#(\d+);|&\w+;/g,t={" ":" ","<":"<",">":">","&":"&",""":'"',"'":"'"};return function(a){return a.replace(e,function(e,a){return"#"==e.charAt(1)?String.fromCharCode(a-0):t.hasOwnProperty(e)?t[e]:e})}}(),s=function(e,t){t=t||new Set;let a=/[A-Z]+[a-z]*|[A-Z]*[a-z]+|'[A-Z]*[a-z]*|[0-9]+|[^A-Za-z0-9'"!\?\-:;,\.\s]+/g,l;for(;null!==(l=a.exec(e));)254>=l[0].charCodeAt(0)?t.add(l[0].toLowerCase()):r(l[0],t);return t},r=function(e,t){e=" "+e.toLowerCase()+" ",t=t||new Set;for(let a=e.length-2;a--;)t.add(e.substring(a,a+3));return t},n=function(e,t){let a=0;return t.forEach(function(t){e.has(t)&&(a+=1)}),a/(e.size+t.size-a)},i=function(e){let a=[];e.pageMap.forEach(function(e){e.score>=0&&a.push(e)}),a.sort(function(e,t){return t.score-e.score||new Date(t.updated)-new Date(e.updated)});let l=Math.min(e.max,a.length);if(e.min<=l){let s=[],r=0;for(;r<l;r++)s.push(e.format.replace(/\${(.*?)}/ig,function(e,t){let l="";return l="$"===t.toLowerCase()?"$":a[r].hasOwnProperty(t)?a[r][t]:""}));if(-1==e.min)for(;r<e.max;r++)s.push(e.dummy||"");let n=(e.prefix||"")+s.join("")+(e.sufix||""),i=e.insertQuery||"#related-posts-site-json",p=e.insertAdjacent||"afterend";t.querySelector(i).insertAdjacentHTML(p,n)}!0!==e.debug&&(e.pageMap=null),e.state="complate"};return e.add=function(t){let a=e;if("loading"==a.state){try{for(let l=0;l<t.feed.entry.length;l++){let s=t.feed.entry[l];for(let r=0;r<s.link.length;r++)if("alternate"==s.link[r].rel){if(!a.pageMap.has(s.link[r].href)){let p=a.gramify(s.link[r].title);!0===a.useSummary&&s.summary&&s.summary.$t&&a.gramify(s.summary.$t,p);let o=n(a.set,p);!0!==a.onlyThumbnail||s.media$thumbnail&&s.media$thumbnail.url||(o=-1),a.pageMap.set(s.link[r].href.split("?")[0],{url:s.link[r].href,title:s.link[r].title,updated:s.updated?s.updated.$t:"",thumbnail:s.media$thumbnail?s.media$thumbnail.url:"",score:o})}break}}}catch(u){}a.count=a.count+1,a.count>=a.limit&&i(a)}},e.init=function(){var n=e;if(!n.state){if(n.state="init",n.url=n.url||location.href,n.title=n.title||t.title,n.labels=n.labels||[],n.url=n.url.split(/\?|#/)[0],n.count=0,n.limit=n.labels.length+(!0===n.useLastPosts?1:0),n.pageMap=new Map,n.pageMap.set(n.url,{score:-1}),null==n.min&&(n.min=1),null==n.max&&(n.max=5),!n.homepageUrl){let p=n.url.match(/^(.+?):\/\/(.+?):?(\d+)?(\/.*)?$/);n.homepageUrl=p[1]+"://"+p[2]+(p[3]?":"+p[3]:"")+"/"}n.homepageUrl=n.homepageUrl.split("?")[0],n.gramify="engramify"==n.useSetType?s:r,n.set=n.gramify(n.title),!0===n.useSnippet&&n.snippet&&(n.snippet=l(n.snippet),n.gramify(n.snippet,n.set));for(let o=0;o<n.pages.length;o++)!1!==n.pages[o].visible&&(n.pages[o].score=n.pages.length+1-o,n.pageMap.set(n.pages[o].url,n.pages[o]));if(n.pageMap.size<n.max){if(n.excludedAnkersQuery){let u=t.querySelectorAll(n.excludedAnkersQuery);for(let f=0;f<u.length;f++)n.pageMap.set(u[f].href,{score:-1})}let m=n.homepageUrl+"feeds/posts/summary",c="?alt=json&callback=FeedRelatedPosts.add"+(n.params?"&"+n.params:""),g=/(^|&)max-results=/.test(n.params);if(0==n.limit)n.min<=n.pageMap.size&&i(n);else if(1==n.labels.length)a(m+"/-/"+n.labels[0]+c+(g?"":"&max-results=100"));else if(2==n.labels.length)a(m+"/-/"+n.labels[0]+c+(g?"":"&max-results=50")),a(m+"/-/"+n.labels[1]+c+(g?"":"&max-results=50"));else for(let d=0;d<n.labels.length;d++)a(m+"/-/"+n.labels[d]+c);!0===n.useLastPosts&&a(m+c)}else i(n);n.state="loading"}},e});
//]]>
</script>
라벨 기반 추천 알고리즘
관련 글은 현재 포스트의 라벨(Label)을 기준으로 최대 5개까지 자동 표시됩니다. 라벨이 동일한 최신 글이 우선 추천되므로, 라벨 정리는 필수입니다.
SEO 최적화 효과
- 검색봇이 내부 페이지를 더 깊이 탐색
- 다양한 키워드 간 자연스러운 연결 구축
- 사용자의 클릭을 유도해 페이지 체류 시간 증가
적용 시 주의사항
- 페이지가 깨질 경우
스크립트 / 스타일 / HTML각각 제거하며 점검 - 포스트마다 반드시 라벨이 1개 이상 포함되어야 정상 작동
- 썸네일이 없는 경우에도 오류 없이 출력됨


