์ž‘๊ฐ€:
    ์ƒ์„ฑ:2026-06-11๋งˆ์ง€๋ง‰ ์—…๋ฐ์ดํŠธ:2026-06-11

    ์›น์‚ฌ์ดํŠธ ์Šค์บ”

    scan ๋ช…๋ น์–ด๋Š” ๊ณต๊ฐœ URL์„ ๊ฐ€์ ธ์™€ ์ด ํŽ˜์ด์ง€ ํฌ๊ธฐ๋ฅผ ์ธก์ •ํ•˜๊ณ  ํŽ˜์ด์ง€์˜ i18n ๋ฐ SEO ์ƒํƒœ๋ฅผ ๊ฐ์‚ฌ(audit)ํ•ฉ๋‹ˆ๋‹ค. HTML ์†์„ฑ, ์ •๊ทœ(canonical) ๋งํฌ, hreflang ํƒœ๊ทธ, robots.txt, sitemap.xml, ๋กœ์ปฌ๋ผ์ด์ฆˆ๋œ ๋‚ด๋ถ€ ๋งํฌ, ๊ทธ๋ฆฌ๊ณ  JavaScript ๋ฒˆ๋“ค์˜ ๋กœ์ผ€์ผ ๊ฐ€์ค‘์น˜๋ฅผ ๋‹ค๋ฃจ๋Š” ํ‰๊ฐ€ ๋ณด๊ณ ์„œ(0-100)๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    ์ถ”๊ฐ€์ ์ธ ์ข…์†์„ฑ์€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. puppeteer๊ฐ€ ์„ค์น˜๋œ ๊ฒฝ์šฐ, ๋” ์ •๋ฐ€ํ•œ ๋ฒˆ๋“ค ๋ถ„์„์„ ์œ„ํ•ด ์ง€์—ฐ ๋กœ๋“œ(lazy-loaded)๋˜๋Š” JavaScript ์ฒญํฌ๋ฅผ ์บก์ฒ˜ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ HTML์— ์„ ์–ธ๋œ ์ฆ‰์‹œ ๋กœ๋“œ๋˜๋Š” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๊ฒ€์‚ฌํ•˜๋Š” ๊ธฐ๋ณธ ๋ฐฉ์‹์œผ๋กœ ๋Œ€์ฒด๋ฉ๋‹ˆ๋‹ค.

    ์‚ฌ์šฉ๋ฒ•

    bash
    npx intlayer scan <url>
    

    ์˜ˆ์‹œ

    bash
    npx intlayer scan https://example.com
    

    ์ถœ๋ ฅ ์˜ˆ์‹œ:

    plaintext
    ๐Ÿ” Scanned https://example.com (basic mode)
    
    Score: 90/100
    Page size: 10.60 MB (HTML 42.31 KB)
    Locales: en, fr, es, de, โ€ฆ
    
    Checks:
      โœ“ html lang attribute
      โœ“ html dir attribute
      โœ“ canonical link
      โœ“ hreflang tags
      โœ“ x-default hreflang
      โœ“ localized internal links
      โš  all internal links localized
      โœ“ current locale detected
      โœ“ robots.txt present
      โœ“ robots.txt keeps locale paths crawlable
      โœ“ sitemap.xml present
      โœ“ sitemap lists every locale
      โœ“ sitemap has alternate links
      โœ“ sitemap has x-default
    
    Bundle locale weight:
      Translations shipped: 120.50 KB
      Unused (other locales): 45.20 KB (37%)
    

    ์˜ต์…˜

    <url> (ํ•„์ˆ˜)

    ์Šค์บ”ํ•  ์ •๊ทœ URL(์˜ˆ: https://example.com).

    --no-deep

    ๋ Œ๋”๋ง ๊ธฐ๋ฐ˜์˜ ์ •๋ฐ€ ์Šค์บ”์„ ๋น„ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค.

    ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ช…๋ น์–ด๋Š” puppeteer๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ—ค๋“œ๋ฆฌ์Šค ๋ธŒ๋ผ์šฐ์ €์—์„œ ํŽ˜์ด์ง€๋ฅผ ๋ Œ๋”๋งํ•˜๊ณ , ์ง€์—ฐ ๋กœ๋“œ๋˜๋Š” JavaScript ์ฒญํฌ๋ฅผ ์บก์ฒ˜ํ•˜์—ฌ ์‹ค์ œ ์ „์†ก ํฌ๊ธฐ๋ฅผ ์ธก์ •ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. puppeteer๊ฐ€ ์„ค์น˜๋˜์–ด ์žˆ์ง€ ์•Š์œผ๋ฉด ์ž๋™์œผ๋กœ ๊ธฐ๋ณธ ๋ชจ๋“œ๋กœ ๋Œ€์ฒด๋ฉ๋‹ˆ๋‹ค.

    puppeteer๊ฐ€ ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์–ด๋„ ๊ธฐ๋ณธ ๋ชจ๋“œ๋ฅผ ๊ฐ•์ œํ•˜๋ ค๋ฉด --no-deep์„ ์ „๋‹ฌํ•˜์‹ญ์‹œ์˜ค.

    ์˜ˆ์‹œ: npx intlayer scan https://example.com --no-deep

    --json

    ์„œ์‹ํ™”๋œ ๋ณด๊ณ ์„œ ๋Œ€์‹  ์ „์ฒด ์Šค์บ” ๊ฒฐ๊ณผ๋ฅผ JSON ๊ฐ์ฒด๋กœ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœ๊ทธ๋žจ ๋ฐฉ์‹์˜ ์†Œ๋น„ ๋˜๋Š” CI ํŒŒ์ดํ”„๋ผ์ธ์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

    ์˜ˆ์‹œ: npx intlayer scan https://example.com --json

    ํ‘œ์ค€ ์„ค์ • ์˜ต์…˜

    • --base-dir โ€” intlayer.config.* ํŒŒ์ผ์„ ์ฐพ๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๊ธฐ์ค€ ๋””๋ ‰ํ† ๋ฆฌ.
    • -e, --env โ€” ๋Œ€์ƒ ํ™˜๊ฒฝ (์˜ˆ: development, production).
    • --env-file โ€” ์‚ฌ์šฉ์ž ์ง€์ • .env ํŒŒ์ผ์˜ ๊ฒฝ๋กœ.
    • --no-cache โ€” ์„ค์ • ์บ์‹œ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค.
    • --verbose โ€” ์„ธ๋ถ€ ๋กœ๊น…์„ ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค (CLI ๋ชจ๋“œ์—์„œ ๊ธฐ๋ณธ๊ฐ’).
    • --prefix โ€” ์‚ฌ์šฉ์ž ์ง€์ • ๋กœ๊ทธ ์ ‘๋‘์‚ฌ.

    ๊ฒ€์‚ฌ ํ•ญ๋ชฉ

    ๊ฒ€์‚ฌ ํ•ญ๋ชฉ ์„ค๋ช… ์ ์ˆ˜ ๊ฐ€์ค‘์น˜
    html lang <html lang="โ€ฆ"> ์†์„ฑ ์กด์žฌ ์—ฌ๋ถ€ 9
    html dir <html dir="โ€ฆ"> ์†์„ฑ ์กด์žฌ ์—ฌ๋ถ€ 3
    canonical <link rel="canonical"> ์กด์žฌ ์—ฌ๋ถ€ 10
    hreflang <link rel="alternate" hreflang="โ€ฆ"> ํƒœ๊ทธ ์กด์žฌ ์—ฌ๋ถ€ 9
    x-default hreflang x-default hreflang ๋Œ€์ฒด ๋งํฌ ์กด์žฌ ์—ฌ๋ถ€ 7
    localized links ํ•˜๋‚˜ ์ด์ƒ์˜ ๋‚ด๋ถ€ ๋งํฌ์— ๋กœ์ผ€์ผ ์„ธ๊ทธ๋จผํŠธ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ์—ฌ๋ถ€ 5
    all links localized ๋ชจ๋“  ๋‚ด๋ถ€ ๋งํฌ์— ๋กœ์ผ€์ผ ์„ธ๊ทธ๋จผํŠธ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ์—ฌ๋ถ€ 5
    current locale ํŽ˜์ด์ง€ ๋กœ์ผ€์ผ ๊ฐ์ง€ ๊ฐ€๋Šฅ ์—ฌ๋ถ€ 3
    robots.txt present /robots.txt๊ฐ€ 200 ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•˜๋Š”์ง€ ์—ฌ๋ถ€ 10
    robots.txt locale paths robots.txt์—์„œ ๋กœ์ผ€์ผ ๊ฒฝ๋กœ๊ฐ€ ์ฐจ๋‹จ๋˜์ง€ ์•Š์•˜๋Š”์ง€ ์—ฌ๋ถ€ 10
    sitemap.xml present /sitemap.xml์ด 200 ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•˜๋Š”์ง€ ์—ฌ๋ถ€ 10
    sitemap locale coverage ๊ฐ์ง€๋œ ๋ชจ๋“  ๋กœ์ผ€์ผ์ด ์‚ฌ์ดํŠธ๋งต์— ๋‚˜ํƒ€๋‚˜๋Š”์ง€ ์—ฌ๋ถ€ 10
    sitemap alternates ์‚ฌ์ดํŠธ๋งต์— hreflang ๋Œ€์ฒด ๋งํฌ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ์—ฌ๋ถ€ 5
    sitemap x-default ์‚ฌ์ดํŠธ๋งต์— x-default hreflang์ด ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ์—ฌ๋ถ€ 5
    unused bundle content JS ๋ฒˆ๋“ค์— ๋ถˆํ•„์š”ํ•˜๊ฒŒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๋กœ์ผ€์ผ ๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š์€์ง€ ์—ฌ๋ถ€ 9

    ์ตœ์ข… ์ ์ˆ˜๋Š” ๋ชจ๋“  ํ†ต๊ณผ๋œ ๊ฒ€์‚ฌ์˜ ๊ฐ€์ค‘์น˜ ํ•ฉ๊ณ„๋ฅผ ๋ฐฑ๋ถ„์œจ(0-100)๋กœ ๋‚˜ํƒ€๋‚ธ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

    ํ”„๋กœ๊ทธ๋žจ ๋ฐฉ์‹์œผ๋กœ ์Šค์บ” ํ•จ์ˆ˜ ์‚ฌ์šฉํ•˜๊ธฐ

    scan ํ•จ์ˆ˜๋Š” @intlayer/cli์—์„œ๋„ ๋‚ด๋ณด๋‚ด์ง€๋ฏ€๋กœ ์‚ฌ์šฉ์ž ์ง€์ • ์Šคํฌ๋ฆฝํŠธ์—์„œ ์ง์ ‘ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

    ts
    import { scan } from "@intlayer/cli";
    
    await scan("https://example.com", {
      deep: false,
      json: false,
    });
    

    ๋” ๋‚ฎ์€ ์ˆ˜์ค€์˜ ์•ก์„ธ์Šค๋ฅผ ์œ„ํ•ด @intlayer/engine/scan์˜ scanWebsite๋Š” ๊ตฌ์กฐํ™”๋œ ScanResult ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค:

    ts
    import { scanWebsite } from "@intlayer/engine/scan";
    
    const result = await scanWebsite("https://example.com", { deep: false });
    console.log(result.score, result.totalPageSize, result.events);