ui 개편 완료
This commit is contained in:
@@ -113,30 +113,35 @@ export function parseRouteSlug(slugInput: string | string[]): ParsedRouteParams
|
||||
} else if (typeof slugInput === 'string' && slugInput.trim()) {
|
||||
tokens = decodeURIComponent(slugInput).split(/[-_\s/]+/)
|
||||
}
|
||||
tokens = tokens.map(t => t.trim()).filter(Boolean)
|
||||
tokens = tokens.map(t => t.trim()).filter(t => Boolean(t) && !/^index\.html?$/i.test(t))
|
||||
|
||||
let matchedRegion: RegionInfo | null = null
|
||||
let matchedTokenIdx = -1
|
||||
let detectedGrade = '중학생'
|
||||
let detectedGradeShort = '중등'
|
||||
let detectedSubjectKey = 'english'
|
||||
let detectedSubjectName = '영어'
|
||||
let detectedSubjectKey = 'math'
|
||||
let detectedSubjectName = '수학'
|
||||
let detectedTerm = '과외'
|
||||
|
||||
// 1. 토큰들 중 동 이름 매칭
|
||||
for (const token of tokens) {
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
const token = tokens[i]
|
||||
const reg = getRegionByDong(token)
|
||||
if (reg) {
|
||||
matchedRegion = reg
|
||||
matchedTokenIdx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 동 이름이 토큰에 없으면 전체 리스트에서 부분 일치 검색
|
||||
if (!matchedRegion && tokens.length > 0) {
|
||||
for (const token of tokens) {
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
const token = tokens[i]
|
||||
const found = (regionsData.list as RegionInfo[]).find(r => token.includes(r.dong) || (token.length >= 2 && r.dong.includes(token)))
|
||||
if (found) {
|
||||
matchedRegion = found
|
||||
matchedTokenIdx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -152,9 +157,10 @@ export function parseRouteSlug(slugInput: string | string[]): ParsedRouteParams
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 학년 추출
|
||||
// 3. 학년 추출 (동 이름 토큰을 제외한 나머지 토큰에서만 검색하여 '고등동', '문학동' 등 별칭 충돌 원천 차단)
|
||||
let hasExplicitGrade = false
|
||||
const fullText = tokens.join(' ')
|
||||
const remainingTokens = tokens.filter((_, idx) => idx !== matchedTokenIdx)
|
||||
const fullText = remainingTokens.join(' ')
|
||||
for (const g of GRADES_LIST) {
|
||||
if (g.aliases.some(a => fullText.includes(a))) {
|
||||
detectedGrade = g.name
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { ParsedRouteParams } from './dataHelper'
|
||||
import { getShortRegionName } from './dataHelper'
|
||||
import { getShortRegionName, getShortSido } from './dataHelper'
|
||||
|
||||
const SUBJECT_IMAGE_MAP: Record<string, string> = {
|
||||
math: '/img/math-tutoring.png',
|
||||
@@ -22,20 +22,25 @@ const CORE_GRADES = ['초등학생', '중학생', '고등학생']
|
||||
export function generateSeoMeta(parsed: ParsedRouteParams, siteName = '공부짝꿍', siteDomain = 'https://soohyun.cloud') {
|
||||
const { sido, sigungu, dong, shortRegionName, grade, subjectKey, subjectName, isRegionOnly } = parsed
|
||||
|
||||
const shortSido = parsed.shortSido || sido.replace(/특별시|광역시|특별자치시|도/g, '').trim()
|
||||
const shortSido = parsed.shortSido || getShortSido(sido)
|
||||
const gradeShort = parsed.gradeShort || (grade === '초등학생' ? '초등' : grade === '고등학생' ? '고등' : '중등')
|
||||
const regionTitle = shortRegionName || getShortRegionName(sido, dong)
|
||||
const regionTitle = shortRegionName || getShortRegionName(sido, dong, sigungu)
|
||||
const subjectImg = SUBJECT_IMAGE_MAP[subjectKey] || '/img/math-tutoring.png'
|
||||
|
||||
// 검색어 [지역] [초등/중등/고등] [과목] 과외 / [지역] [초등/중등/고등] 과외 완벽 매칭 타이틀
|
||||
const dongHash = Array.from(dong || '').reduce((acc, ch) => acc + ch.charCodeAt(0), 0)
|
||||
const baseSubjects = ['수학', '영어', '국어', '과학', '사회']
|
||||
const rotatedSubjects = baseSubjects.map((_, i) => baseSubjects[(dongHash + i) % baseSubjects.length])
|
||||
const rotatedSubText = rotatedSubjects.map(s => `${dong}${s}과외선생님`).join(', ')
|
||||
|
||||
const pageTitle = isRegionOnly
|
||||
? `${shortSido} 중등 수학 과외 · ${shortSido} 중등 과외 | ${regionTitle} 초·중·고 1:1 맞춤 과외`
|
||||
: `${shortSido} ${gradeShort} ${subjectName} 과외 · ${regionTitle} ${grade} ${subjectName}과외 | ${shortSido} ${gradeShort} 과외 1:1 매칭`
|
||||
|
||||
// 첫 문장이 정확한 타겟 키워드로 시작하는 고의도 메타 디스크립션 (더세이브 동기화)
|
||||
const pageDescription = isRegionOnly
|
||||
? `${shortSido} 중등 수학 과외, ${shortSido} 중등 과외, ${dong} 중등 수학 과외 전문 ${siteName}! ${regionTitle} 초등·중등·고등 국영수사과 1:1 맞춤 과외, 검증된 전문 선생님 무료 시범수업과 과외비 비교를 확인하세요.`
|
||||
: `${shortSido} ${gradeShort} ${subjectName} 과외, ${shortSido} ${gradeShort} 과외, ${dong} ${gradeShort} ${subjectName} 과외 전문 ${siteName}! ${regionTitle} ${grade} ${subjectName} 1:1 방문·화상 맞춤 수업으로 내신·수능 성적 향상을 책임집니다. 과외비 투명 공개 및 무료 시범수업 신청하세요.`
|
||||
? `${shortSido} 중등 수학 과외, ${shortSido} 중등 과외, ${dong} 중등 수학 과외 전문 ${siteName}! ${regionTitle} 초등·중등·고등 국영수사과 1:1 맞춤 과외, 검증된 전문 선생님 무료 시범수업과 과외비 비교(${rotatedSubText})를 확인하세요.`
|
||||
: `${shortSido} ${gradeShort} ${subjectName} 과외, ${shortSido} ${gradeShort} 과외, ${dong} ${gradeShort} ${subjectName} 과외 전문 ${siteName}! ${regionTitle} ${grade} ${subjectName} 1:1 방문·화상 맞춤 수업으로 내신·수능 성적 향상을 책임집니다. 과외비 투명 공개 및 무료 시범수업(${rotatedSubText})을 신청하세요.`
|
||||
|
||||
const pageKeywords = `${shortSido} ${gradeShort} ${subjectName} 과외, ${shortSido} ${gradeShort} 과외, ${dong} ${gradeShort} ${subjectName} 과외, ${dong} ${gradeShort} 과외, ${shortSido}${gradeShort}${subjectName}과외, ${shortSido}${gradeShort}과외, ${shortSido} 중등 수학 과외, ${shortSido} 중등 과외, ${shortSido} 고등 수학 과외, ${shortSido} 초등 수학 과외, ${regionTitle} ${subjectName}과외, ${dong} ${subjectName}과외, ${dong} ${grade} ${subjectName}과외, ${dong}과외, ${sigungu}과외, ${shortSido}과외`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user