// ─── SEO engine ────────────────────────────────────────────────────────────── // 1) page 상태 → 실제 URL (/solutions//) 동기화, 뒤로가기 지원 // 2) title · description · keywords · canonical · hreflang(ko/en) · OG · Twitter 갱신 // 3) JSON-LD (Organization · WebSite · BreadcrumbList · Product/Service) 주입 // 4) 화면에는 안 보이지만 크롤러·AI 검색이 읽는 시맨틱 인덱스 블록 유지 // 신규 솔루션은 constants.jsx solutions.items 에 추가만 하면 자동으로 전부 반영됨. // 제품별 제조사 — 3ES Soft 는 공급·구축·운영 담당(제조사 아님) window.SOL_VENDOR = { spamout:'NetNSecu', checkout:'NetNSecu', arch5:'NetNSecu', mailinsight:'NetNSecu', genian:'Genians', edr:'Genians', mdr:'Genians', netwitness:'NetWitness', sniper:'SGA Solutions', eset:'ESET', dbsafer:'PNPSecure', cce:'SSR', cve:'SSR', catchsecu:'CatchSecu', }; window.SITE = { origin: 'https://www.3es.co.kr', name: '㈜삼에스소프트', nameEn: '3ES Soft Co., Ltd.' }; // page 키 ↔ URL 경로 window.SEO_ROUTES = { home:'/', about:'/company/', solutions:'/solutions/', partner:'/partner/', topology:'/topology/', support:'/support/', news:'/insights/', contact:'/contact/', privacy:'/privacy/', }; window.pathForPage = function (page) { if (window.SEO_ROUTES[page]) return window.SEO_ROUTES[page]; if (page && page.indexOf('sol_') === 0) return '/solutions/' + page.slice(4) + '/'; if (page && page.indexOf('article_') === 0) return '/insights/' + page.slice(8) + '/'; return '/'; }; window.pageForPath = function (path) { const p = (path || '/').replace(/\/+$/, '/') || '/'; for (const k in window.SEO_ROUTES) if (window.SEO_ROUTES[k] === p) return k; const m = p.match(/^\/solutions\/([a-z0-9_-]+)\/?$/i); if (m) return 'sol_' + m[1]; const n2 = p.match(/^\/insights\/([a-z0-9_-]+)\/?$/i); if (n2) return 'article_' + n2[1]; return null; }; const _meta = (sel, attr, key, val) => { let el = document.head.querySelector(sel); if (!el) { el = document.createElement('meta'); el.setAttribute(attr, key); document.head.appendChild(el); } el.setAttribute('content', val); }; const _link = (rel, href, extra) => { const sel = `link[rel="${rel}"]` + (extra ? `[hreflang="${extra}"]` : ':not([hreflang])'); let el = document.head.querySelector(sel); if (!el) { el = document.createElement('link'); el.setAttribute('rel', rel); if (extra) el.setAttribute('hreflang', extra); document.head.appendChild(el); } el.setAttribute('href', href); }; const _ld = (id, obj) => { let el = document.getElementById(id); if (!el) { el = document.createElement('script'); el.type = 'application/ld+json'; el.id = id; document.head.appendChild(el); } el.textContent = JSON.stringify(obj); }; // 제품 페이지가 카테고리 페이지를 공유하는 경우(동일 콘텐츠) — 정규 URL로 연결해 중복 색인 방지 window.SEO_ALIAS = { catchsecu: 'privacy' }; // 현재 page 에 해당하는 솔루션 아이템 찾기 window.solItemFor = function (page, lang) { if (!page || page.indexOf('sol_') !== 0) return null; const raw = page.slice(4); const key = window.SEO_ALIAS[raw] || raw; const items = (window.T[lang] && window.T[lang].solutions.items) || []; return items.find(i => i.key === key) || null; }; // ─── 메인 훅 ───────────────────────────────────────────────────────────────── window.useSEO = function (page, lang) { React.useEffect(() => { const S = window.SITE, isKo = lang !== 'en'; const path = window.pathForPage(page); const sol = window.solItemFor(page, lang); // 별칭 페이지(예: /solutions/catchsecu/)는 정규 URL을 원본 솔루션으로 지정 const canonPath = sol ? '/solutions/' + sol.key + '/' : path; const url = S.origin + canonPath; const brand = isKo ? S.name : S.nameEn; // URL 동기화 (admin 등 내부 화면은 제외) if (page !== 'admin' && location.pathname !== path) history.pushState({ page }, '', path + location.search); let title, desc, kws; // 인사이트 기사 — 개별 제목·설명·JSON-LD const art = (page && page.indexOf('article_') === 0 && typeof window.latestNews === 'function') ? window.latestNews(999).find(x => x.id === page.slice(8)) : null; if (art) { title = isKo ? `${art.title} | 보안·AI 인사이트 · ${brand}` : `${art.title} | Insights · ${brand}`; desc = art.summary || art.desc || ''; kws = [...new Set([...(art.tags || []).map(x => String(x).replace(/^#/, '')), art.cat, isKo?'보안 인사이트':'security insights', isKo?'삼에스소프트':'3ES Soft'].filter(Boolean))]; } else if (sol) { const kwList = window.keywordsFor(sol, lang); title = isKo ? `${sol.title} (${sol.eng}) | ${kwList[3] || sol.eng} · ${brand}` : `${sol.title} — ${sol.eng} | ${brand}`; desc = `${sol.desc} ${isKo ? `${sol.title} 도입 상담, 견적, 구축 사례는 삼에스소프트에 문의하세요.` : `Talk to 3ES Soft for ${sol.title} pricing, deployment, and case studies.`}`; kws = kwList; } else { const pageMeta = { home: [isKo?`${brand} | IT 보안 솔루션 컨설팅·구축·운영 전문 기업`:`${brand} | Enterprise IT Security Solutions`, isKo?'이메일 보안, 시스템 보안, 네트워크 보안, 개인정보 보호, AI 보안 솔루션을 고객 환경에 맞게 제안하고 구축·운영합니다.':'Email, system, network, privacy and AI security solutions — designed, deployed and operated for your environment.'], about: [isKo?`회사소개 | ${brand}`:`Company | ${brand}`, isKo?'보안 컨설팅부터 구축, 운영까지 책임지는 IT 보안 파트너 삼에스소프트를 소개합니다.':'3ES Soft — a security partner responsible for consulting, deployment and operations.'], topology:[isKo?`보안 토폴로지 | 기업 보안 아키텍처 한눈에 보기 · ${brand}`:`Security Topology | ${brand}`, isKo?'경계부터 데이터까지 보안 계층이 어떻게 연결되는지 확인하고, 공격 시뮬레이션과 자가 진단으로 우리 회사에 비어 있는 계층을 찾아보세요.':'See how every security layer connects — run attack simulations and assess the gaps in your own stack.'], solutions:[isKo?`보안 솔루션 전체보기 | ${brand}`:`All Security Solutions | ${brand}`, isKo?'이메일·시스템·네트워크·데이터·개인정보·AI 보안까지 영역별 전문 솔루션을 한눈에 확인하세요.':'Browse specialized solutions across email, system, network, data, privacy and AI security.'], partner:[isKo?`파트너 협업 | ${brand}`:`Partnership | ${brand}`, isKo?'총판·리셀러·기술 파트너와 함께 보안 시장을 확장합니다. 파트너 등록을 문의하세요.':'Distributor, reseller and technology partnerships with 3ES Soft.'], support:[isKo?`고객지원 | ${brand}`:`Support | ${brand}`, isKo?'기술지원, 장애 대응, 유지보수 문의 — 도입 이후 운영까지 함께합니다.':'Technical support, incident response and maintenance for deployed solutions.'], news: [isKo?`보안·AI 인사이트 | ${brand}`:`Security & AI Insights | ${brand}`, isKo?'보안 뉴스, AI 동향, IT 트렌드, 규제·컴플라이언스 소식을 정리해 전합니다.':'Security news, AI trends, IT updates and compliance briefings.'], contact:[isKo?`문의하기 | ${brand}`:`Contact | ${brand}`, isKo?'솔루션 도입 상담, 견적 요청, 데모 신청을 남겨주시면 담당자가 회신드립니다.':'Request a consultation, quote or demo — our team will get back to you.'], privacy:[isKo?`개인정보 처리방침 | ${brand}`:`Privacy Policy | ${brand}`, isKo?'삼에스소프트 개인정보 처리방침입니다.':'Privacy policy of 3ES Soft.'], }[page] || [isKo?`${brand} | IT 보안 솔루션 전문 기업`:`${brand} | IT Security Solutions`, '']; title = pageMeta[0]; desc = pageMeta[1]; // 전 솔루션 대표 키워드를 합쳐 사이트 전역 키워드 구성 const items = (window.T[lang] && window.T[lang].solutions.items) || []; kws = items.flatMap(i => window.keywordsFor(i, lang).slice(0, 3)); kws = [...new Set([isKo?'IT 보안 솔루션':'IT security solution', isKo?'보안 솔루션 전문 기업':'security solution provider', isKo?'삼에스소프트':'3ES Soft', ...kws])]; } document.title = title; document.documentElement.lang = isKo ? 'ko' : 'en'; _meta('meta[name="description"]', 'name', 'description', desc); _meta('meta[name="keywords"]', 'name', 'keywords', kws.join(', ')); _meta('meta[name="robots"]', 'name', 'robots', page === 'admin' ? 'noindex,nofollow' : 'index,follow,max-image-preview:large,max-snippet:-1'); _meta('meta[property="og:title"]', 'property', 'og:title', title); _meta('meta[property="og:description"]', 'property', 'og:description', desc); _meta('meta[property="og:url"]', 'property', 'og:url', url); _meta('meta[property="og:locale"]', 'property', 'og:locale', isKo ? 'ko_KR' : 'en_US'); _meta('meta[name="twitter:title"]', 'name', 'twitter:title', title); _meta('meta[name="twitter:description"]', 'name', 'twitter:description', desc); _link('canonical', url); // KO/EN 이 같은 URL 을 쓰는 동안은 hreflang 을 선언하지 않는다 (잘못된 신호 방지). // 추후 /en/ 경로를 분리하면 다시 활성화할 것. document.head.querySelectorAll('link[rel="alternate"][hreflang]').forEach(el=>el.remove()); // ── JSON-LD ── _ld('ld-website', { '@context':'https://schema.org','@type':'WebSite', name: brand, url: S.origin + '/', inLanguage: isKo ? 'ko-KR' : 'en-US', potentialAction: { '@type':'SearchAction', target: S.origin + '/solutions/?q={search_term_string}', 'query-input':'required name=search_term_string' }, }); const crumbs = [{ '@type':'ListItem', position:1, name: isKo?'홈':'Home', item: S.origin + '/' }]; if (art) { crumbs.push({ '@type':'ListItem', position:2, name: isKo?'보안·AI 인사이트':'Insights', item: S.origin + '/insights/' }, { '@type':'ListItem', position:3, name: art.title, item: url }); } else if (sol) { crumbs.push({ '@type':'ListItem', position:2, name: isKo?'솔루션':'Solutions', item: S.origin + '/solutions/' }, { '@type':'ListItem', position:3, name: sol.title, item: url }); } else if (page !== 'home') crumbs.push({ '@type':'ListItem', position:2, name: title.split('|')[0].trim(), item: url }); _ld('ld-breadcrumb', { '@context':'https://schema.org','@type':'BreadcrumbList', itemListElement: crumbs }); if (art) { const el1 = document.getElementById('ld-product'); if (el1) el1.remove(); const el2 = document.getElementById('ld-service'); if (el2) el2.remove(); _ld('ld-article', { '@context':'https://schema.org','@type':'NewsArticle', headline: art.title, description: art.summary || '', datePublished: String(art.pub || art.date || '').replace(/\./g, '-'), inLanguage: isKo ? 'ko-KR' : 'en-US', articleSection: art.cat || '', keywords: (art.tags || []).map(x => String(x).replace(/^#/, '')).join(', '), author: { '@type':'Organization', name: art.author || brand }, publisher: { '@type':'Organization', name: brand, url: S.origin + '/' }, mainEntityOfPage: { '@type':'WebPage', '@id': url }, }); } else if (sol) { const elA = document.getElementById('ld-article'); if (elA) elA.remove(); _ld('ld-product', { '@context':'https://schema.org','@type':'Product', name: sol.title, alternateName: sol.eng, description: sol.desc, category: isKo?'IT 보안 솔루션':'IT Security Solution', brand: { '@type':'Brand', name: (window.SOL_VENDOR && window.SOL_VENDOR[sol.key]) || brand }, url, keywords: window.keywordsFor(sol, lang).join(', '), offers: { '@type':'Offer', priceCurrency: isKo?'KRW':'USD', availability:'https://schema.org/InStock', url, seller:{ '@type':'Organization', name: brand } }, isRelatedTo: (sol.tags||[]).map(tg => ({ '@type':'Thing', name: tg })), }); _ld('ld-service', { '@context':'https://schema.org','@type':'Service', serviceType: sol.eng, name: sol.title, description: sol.desc, provider:{ '@type':'Organization', name: brand, url: S.origin + '/' }, areaServed:{ '@type':'Country', name: isKo?'대한민국':'South Korea' }, availableChannel:{ '@type':'ServiceChannel', serviceUrl: url }, }); } else { const el1 = document.getElementById('ld-product'); if (el1) el1.remove(); const el2 = document.getElementById('ld-service'); if (el2) el2.remove(); const el3 = document.getElementById('ld-article'); if (el3) el3.remove(); if (page === 'solutions' || page === 'home') { const items = (window.T[lang] && window.T[lang].solutions.items) || []; _ld('ld-itemlist', { '@context':'https://schema.org','@type':'ItemList', name: isKo?'삼에스소프트 보안 솔루션':'3ES Soft Security Solutions', numberOfItems: items.length, itemListElement: items.map((i, n) => ({ '@type':'ListItem', position:n+1, name:i.title, description:i.desc, url: S.origin + '/solutions/' + i.key + '/' })), }); } } }, [page, lang]); }; // ─── 크롤러·AI 검색용 시맨틱 인덱스 (화면에는 보이지 않음) ──────────────────── window.SEOIndex = function ({ lang, setPage }) { const isKo = lang !== 'en'; const items = (window.T[lang] && window.T[lang].solutions.items) || []; const go = (e, key) => { e.preventDefault(); setPage('sol_' + key); }; return (

{isKo ? '삼에스소프트 보안 솔루션 전체 목록' : 'All 3ES Soft Security Solutions'}

); };