게시판 목록 페이지의 메타 설명이 전부 똑같이 출력되고 있었습니다. 공지사항, 자유게시판, 자료실, 게임 게시판이 모두 같은 문장을 달고 있었고, 검색 결과에서도 차이가 거의 없어 보였습니다.
처음에는 목록 페이지라서 어쩔 수 없다고 생각했습니다. 게시글 상세처럼 본문이 있는 것도 아니고, 게시판마다 따로 설명을 써둔 것도 아니었기 때문입니다. 하지만 그냥 두면 사이트 전체에 중복 메타 설명이 계속 쌓이는 구조였습니다.
이 글은 메타 설명을 무조건 자동 생성하자는 글이 아닙니다. 직접 입력한 설명이 있으면 그것을 먼저 쓰고, 없을 때만 최신 게시글 제목을 조합해 게시판별 설명을 만드는 방식으로 정리한 과정입니다.
모든 게시판 설명이 같았던 상황
기존 공통 헤더에는 이런 메타 설명이 들어 있었습니다.
<meta name="description" content="누구나 쉽게 만드는 무료 홈페이지">
홈페이지 메인에서는 쓸 수 있는 문장일 수 있습니다. 하지만 모든 게시판 목록에 똑같이 들어가면 문제가 됩니다.
공지사항 → 누구나 쉽게 만드는 무료 홈페이지
자유게시판 → 누구나 쉽게 만드는 무료 홈페이지
자료실 → 누구나 쉽게 만드는 무료 홈페이지
게임 게시판 → 누구나 쉽게 만드는 무료 홈페이지
검색 결과에서 보면 게시판 이름만 다르고 설명은 모두 같습니다. 사용자는 어떤 게시판에 어떤 글이 있는지 알기 어렵고, 검색엔진 입장에서도 목록 페이지의 차이를 파악하기 어렵습니다.
게시판 목록은 글 제목이 핵심 내용
게시판 목록 페이지에는 긴 본문이 없습니다. 대신 그 게시판 안에 들어 있는 글 제목들이 있습니다.
그래서 최신 글 제목 몇 개를 조합하면 게시판마다 다른 설명을 만들 수 있다고 봤습니다.
물불게임 바로가기, 백층탈출 2 공략, 지오메트리대쉬 난이도 정리...
사람이 직접 쓴 설명만큼 자연스럽지는 않습니다. 하지만 모든 게시판이 같은 기본 문장을 쓰는 것보다는 훨씬 낫습니다.
핵심은 자동 생성 설명을 1순위로 두지 않는 것입니다. 사람이 직접 입력한 설명이 있으면 그 값을 먼저 쓰고, 없을 때만 자동 생성으로 보완하는 구조가 안전했습니다.
최신 글 제목으로 설명 만들기
게시판 번호를 기준으로 최신 글 제목을 가져와 쉼표로 이어 붙였습니다.
<?php
function buildBoardDescription(PDO $pdo, int $boardNo, string $fallback): string
{
$stmt = $pdo->prepare(
'SELECT title
FROM posts
WHERE board_no = ?
AND is_deleted = 0
ORDER BY created_at DESC
LIMIT 8'
);
$stmt->execute([$boardNo]);
$titles = $stmt->fetchAll(PDO::FETCH_COLUMN);
if (!$titles) {
return $fallback;
}
$text = implode(', ', $titles);
$text = strip_tags($text);
$text = html_entity_decode($text, ENT_QUOTES, 'UTF-8');
$text = preg_replace('/\s+/u', ' ', $text);
$text = trim($text);
if (mb_strlen($text, 'UTF-8') > 150) {
$text = mb_substr($text, 0, 147, 'UTF-8') . '...';
}
return $text;
}
?>
삭제된 글은 제외했습니다. 이미 사라진 글 제목이 게시판 설명에 남으면 사용자에게도 검색엔진에게도 맞지 않는 설명이 됩니다.
LIMIT 8은 너무 많은 제목을 가져오지 않기 위한 기준이었습니다. 어차피 최종 설명은 150자 안팎으로 자르기 때문에 제목을 과하게 가져올 필요는 없었습니다.
직접 입력 설명을 우선 사용
자동 생성보다 더 좋은 것은 관리자가 직접 쓴 설명입니다. 주요 게시판은 사람이 한 문장으로 설명하는 편이 더 자연스럽습니다.
그래서 우선순위를 이렇게 잡았습니다.
1. 관리자가 직접 입력한 게시판 설명
2. 없으면 최신 글 제목 조합
3. 글도 없으면 기본 문구
코드로는 이런 흐름입니다.
<?php
$manualDesc = trim($board['meta_description'] ?? '');
if ($manualDesc !== '') {
$desc = $manualDesc;
} else {
$desc = buildBoardDescription(
$pdo,
$boardNo,
$boardName . ' 게시판 글 목록입니다.'
);
}
?>
이렇게 하면 중요한 게시판은 직접 작성한 설명을 쓰고, 나머지 게시판은 자동 생성으로 최소한의 차이를 만들 수 있습니다.
출력 직전 이스케이프 처리
메타 설명은 HTML 속성 안에 들어갑니다. 게시글 제목에 따옴표나 특수문자가 들어 있으면 태그가 깨질 수 있습니다.
그래서 출력 직전에 반드시 이스케이프했습니다.
<?php
echo '<meta name="description" content="'
. htmlspecialchars($desc, ENT_QUOTES, 'UTF-8')
. '">' . "\n";
?>
예를 들어 제목에 큰따옴표가 들어간 경우입니다.
"초보자 공략" 정리
이스케이프하지 않으면 content="..." 속성이 중간에서 끊길 수 있습니다. 자동 생성 메타 태그는 사용자 입력이 섞이기 쉬우므로 마지막 출력 단계에서 처리하는 것이 안전했습니다.
title과 H1도 같은 기준으로 정리
메타 설명만 바꾸면 부족했습니다. 게시판 목록 페이지의 title과 H1도 같이 맞춰야 검색 결과와 본문 구조가 자연스럽습니다.
<?php
$pageTitle = $boardName . ' | ' . $siteName;
echo '<title>' . htmlspecialchars($pageTitle, ENT_QUOTES, 'UTF-8') . '</title>' . "\n";
echo '<h1>' . htmlspecialchars($boardName, ENT_QUOTES, 'UTF-8') . '</h1>' . "\n";
?>
게시판 목록에서는 게시판 이름이 페이지 주제입니다. 상세 페이지에서는 글 제목이 H1이 되어야 하지만, 목록 페이지에서는 게시판 이름이 H1인 편이 자연스러웠습니다.
검색 결과 페이지라면 또 다르게 처리했습니다.
<?php
if (!empty($keyword)) {
$pageTitle = $keyword . ' 검색 결과 | ' . $siteName;
$h1 = $keyword . ' 검색 결과';
}
?>
목록, 상세, 검색 결과가 같은 템플릿을 쓰는 경우에는 title, description, H1을 같은 기준으로 분기해야 했습니다.
글이 없는 게시판의 기본 문구
글이 하나도 없는 게시판에서는 최신 글 제목을 만들 수 없습니다. 이때 빈 description을 출력하면 검색 결과에서 더 어색해질 수 있습니다.
그래서 게시판 이름을 활용한 기본 문구를 넣었습니다.
<?php
$fallback = $boardName . ' 게시판 글 목록입니다.';
$desc = buildBoardDescription($pdo, $boardNo, $fallback);
?>
예시는 아래처럼 됩니다.
공지사항 게시판 글 목록입니다.
자료실 게시판 글 목록입니다.
완벽한 문장은 아니지만 모든 페이지가 같은 문장을 갖는 것보다는 낫습니다. 이후 중요한 게시판부터 직접 설명을 채워 넣으면 됩니다.
검색엔진이 항상 그대로 쓰지는 않음
메타 설명을 넣어도 구글이 반드시 그 문장을 검색 결과에 그대로 보여주는 것은 아닙니다. 검색어와 페이지 내용에 따라 본문 일부를 가져다 쓸 수도 있습니다.
그래도 목록 페이지에서는 메타 설명을 넣는 의미가 있었습니다. 게시판 목록은 본문이 짧고 반복 구조가 많아서, 적절한 설명이 없으면 기본 문구나 메뉴 텍스트가 검색 결과에 노출될 수 있기 때문입니다.
특히 게시글 제목을 조합한 설명은 롱테일 키워드에도 도움이 됐습니다.
게임명, 공략, 오류 해결, 업데이트 안내
게시판 안에 어떤 글이 있는지 검색 결과에서 조금 더 드러났습니다.
중복 설명 여부 확인
수정 후에는 페이지 소스에서 description이 게시판마다 다르게 출력되는지 확인했습니다.
curl -s https://example.com/mysite/board/856 | grep -i 'name="description"'
curl -s https://example.com/mysite/board/900 | grep -i 'name="description"'
그리고 따옴표 때문에 태그가 깨지지 않는지도 봤습니다.
<meta name="description" content="물불게임 바로가기, 백층탈출 2 공략, 지오메트리대쉬 난이도 정리...">
서치콘솔에서는 바로 반영되지는 않았습니다. 하지만 시간이 지나면서 같은 설명이 반복되던 목록 페이지가 조금씩 다른 검색어로 노출되기 시작했습니다.
적용 후 달라진 점
수정 후에는 게시판별 설명이 서로 달라졌습니다.
- 모든 게시판에 같은 기본 설명이 들어가던 문제 감소
- 최신 글 제목 기반으로 게시판 내용이 드러남
- 주요 게시판은 직접 입력 설명을 우선 사용
- 글이 없는 게시판은 기본 문구로 처리
- title, description, H1 분기 기준 정리
- 검색 결과에서 게시판별 차이가 조금 더 보임
자동 생성 설명은 완벽한 해결책은 아니었습니다. 하지만 중복 설명을 줄이고, 직접 설명을 채우기 전까지 사용할 수 있는 현실적인 중간 단계였습니다.
게시판 메타 설명 체크리스트
자동 생성은 빈칸을 메우는 보조 장치
게시판 메타 설명은 가능하면 사람이 직접 쓰는 것이 가장 좋습니다. 게시판의 목적과 주요 콘텐츠를 한 문장으로 설명하는 것이 최신 글 제목 나열보다 자연스럽기 때문입니다.
하지만 오래된 사이트에 게시판이 수십 개 있다면 한 번에 모두 작성하기 어렵습니다. 이럴 때 최신 글 제목을 조합한 자동 생성 설명은 중복 description을 줄이는 임시 방편으로 쓸 수 있었습니다.
제가 얻은 기준은 단순합니다. 직접 입력값이 있으면 그것을 쓰고, 없으면 최신 글 제목으로 보완하고, 글도 없으면 기본 문구를 사용합니다. 그리고 어떤 방식이든 출력 직전 이스케이프와 길이 제한은 반드시 적용합니다.
메타 설명은 검색 순위를 직접 올리는 버튼은 아니지만, 검색 결과에서 사용자가 클릭할지 판단하는 문장입니다. 모든 게시판이 같은 문장을 달고 있다면 자동 생성이라도 넣어 페이지별 차이를 만드는 편이 나았습니다.