Skip to content

SEO 최적화 홍보 웹사이트(website/) 추가 - #10

Merged
umsungjun merged 2 commits into
mainfrom
feat/website
Aug 6, 2026
Merged

SEO 최적화 홍보 웹사이트(website/) 추가#10
umsungjun merged 2 commits into
mainfrom
feat/website

Conversation

@umsungjun

Copy link
Copy Markdown
Owner
  • Next.js 15 App Router 기반 독립 홍보 사이트 신설 (npm 배포본 소비, Vercel Root Directory = website 배포)
  • route group 이중 루트 레이아웃으로 영어(/)·한국어(/ko) 구성, hreflang/canonical/OG/JSON-LD/robots/sitemap 적용
  • 3D 디바이스 쇼케이스(6종), SSR 계약 라이브 데모, npm/yarn/pnpm 클릭 복사 위젯, 사용 예시 섹션 구현
  • 정적 OG 이미지(public/og.png)와 Google Search Console 인증 파일 추가
  • 루트 website 스크립트, eslint ignore, CLAUDE.md, 양 README 반영

- Next.js 15 App Router 기반 독립 홍보 사이트 신설 (npm 배포본 소비, Vercel Root Directory = website 배포)
- route group 이중 루트 레이아웃으로 영어(/)·한국어(/ko) 구성, hreflang/canonical/OG/JSON-LD/robots/sitemap 적용
- 3D 디바이스 쇼케이스(6종), SSR 계약 라이브 데모, npm/yarn/pnpm 클릭 복사 위젯, 사용 예시 섹션 구현
- 정적 OG 이미지(public/og.png)와 Google Search Console 인증 파일 추가
- 루트 website 스크립트, eslint ignore, CLAUDE.md, 양 README 반영

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

There are verified security and correctness issues (missing noopener on _blank links, unhandled clipboard failures, and a broken .next type reference) that should be fixed before merging.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Pull request overview

Adds a standalone Next.js (App Router) promo/landing website under website/ to showcase react-device-check with bilingual routing and SEO primitives, while keeping the library/examples workflow intact.

Changes:

  • Introduces a self-contained website/ Next.js app (routes, components, styling, localized copy).
  • Implements SEO essentials (metadata builder, JSON-LD, sitemap/robots, OpenGraph/Twitter image references, Google Search Console verification file).
  • Updates repo-level docs/scripts/config to reference and accommodate the website (README links, pnpm website, ESLint ignores, CLAUDE.md).
File summaries
File Description
website/tsconfig.json Website TypeScript configuration for Next.js App Router project.
website/public/google6b4dd67b252bbb17.html Adds Google Search Console verification file.
website/pnpm-lock.yaml Locks website dependencies for reproducible installs.
website/package.json Defines website package, scripts, and dependencies.
website/next.config.ts Next.js config: ESLint ignore + tracing root pinning.
website/next-env.d.ts Next.js TypeScript environment references for the website.
website/lib/seo.ts Centralizes SEO constants and metadata/JSON-LD builders.
website/lib/fonts.ts Sets up self-hosted Google fonts via next/font.
website/content/types.ts Strongly typed localization shape for visible strings.
website/content/ko.ts Korean landing-page copy content.
website/content/en.ts English landing-page copy content.
website/content/code.ts Locale-independent install/usage snippet data for UI.
website/components/LiveDemo.tsx Client component live demo powered by useDevice().
website/components/Landing.tsx Main landing-page composition + JSON-LD injection.
website/components/InstallTabs.tsx Client install command tabs + click-to-copy behavior.
website/components/DeviceShowcase.tsx Static multi-device showcase visuals and copy layout.
website/components/CodeBlock.tsx Reusable code block component.
website/app/sitemap.ts Sitemap generation for en/ko routes with alternates.
website/app/robots.ts Robots metadata endpoint with sitemap reference.
website/app/icon.svg App icon for the website.
website/app/globals.css Complete styling + responsive layout + design tokens.
website/app/(ko)/layout.tsx Korean route-group root layout with lang="ko".
website/app/(ko)/ko/page.tsx Korean home page wiring to localized content + metadata.
website/app/(en)/page.tsx English home page wiring to localized content + metadata.
website/app/(en)/layout.tsx English route-group root layout with lang="en".
README.md Adds website/live demo link and table formatting adjustments.
README.ko.md Adds website/live demo link and table formatting adjustments.
package.json Adds pnpm website convenience script.
eslint.config.mjs Excludes website/ from repo-root ESLint.
CLAUDE.md Documents the website architecture/deployment in repo guidance.
Review details

Files not reviewed (1)

  • website/pnpm-lock.yaml: Generated file

Suppressed comments (5)

website/components/Landing.tsx:95

  • Links opened with target="_blank" should include rel="noopener" (in addition to noreferrer) to prevent the opened page from gaining access to window.opener (tabnabbing risk).
              rel="noreferrer"

website/components/Landing.tsx:56

  • Links opened with target="_blank" should include rel="noopener" (in addition to noreferrer) to prevent the opened page from gaining access to window.opener (tabnabbing risk).
            <a href={NPM_URL} target="_blank" rel="noreferrer">

website/components/Landing.tsx:203

  • Links opened with target="_blank" should include rel="noopener" (in addition to noreferrer) to prevent the opened page from gaining access to window.opener (tabnabbing risk).
            <a href={readmeUrl} target="_blank" rel="noreferrer">

website/components/Landing.tsx:215

  • Links opened with target="_blank" should include rel="noopener" (in addition to noreferrer) to prevent the opened page from gaining access to window.opener (tabnabbing risk).
            <a href={GITHUB_URL} target="_blank" rel="noreferrer">

website/components/Landing.tsx:218

  • Links opened with target="_blank" should include rel="noopener" (in addition to noreferrer) to prevent the opened page from gaining access to window.opener (tabnabbing risk).
            <a href={NPM_URL} target="_blank" rel="noreferrer">
  • Files reviewed: 27/31 changed files
  • Comments generated: 3
  • Review effort level: Lite

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

Comment thread website/components/Landing.tsx Outdated
Comment on lines +20 to +23
const handleCopy = async () => {
await navigator.clipboard.writeText(INSTALL_COMMANDS[active].command);
setCopied(true);
};
Comment thread CLAUDE.md Outdated

### Website

`website/` is a standalone Next.js 15 promo/landing site (own lockfile, not a workspace member) consuming the **published npm package** — unlike both examples, it needs no root build. English at `/`, Korean at `/ko` via two route-group root layouts (each sets its own `<html lang>`); hreflang/canonical/OG metadata come from `website/lib/seo.ts` (`SITE_URL` is the single deploy-URL definition). The OG image is served by `app/og/route.tsx` (a plain route handler — the `opengraph-image` file convention does not inject meta tags across route-group root layouts). Deployed on Vercel with Root Directory = `website`; excluded from CI, lint, size-limit, and the Playwright E2E matrix. The examples' ports and `data-testid` contracts are untouched by it.
… OG doc fix

- Add noopener to rel of target="_blank" external links (noreferrer already blocks the opener; kept explicit for defense in depth)
- Wrap clipboard copy in try/catch so permission denials and insecure contexts fail silently without unhandled rejections
- Update the CLAUDE.md OG image description to match the actual implementation (static public/og.png)

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The website’s TS path alias setup is incomplete (missing baseUrl), which can break @/ imports during typechecking/build.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Review details

Files not reviewed (1)

  • website/pnpm-lock.yaml: Generated file

Suppressed comments (2)

website/components/DeviceShowcase.tsx:159

  • This relies on device.values always having type and os as the first two entries; reordering that array will silently swap or break the displayed verdict. Looking up by key makes the component resilient to changes in DEVICES.
        const meta = strings.devices[index];
        const [[, type], [, os]] = device.values;
        return (

website/components/Landing.tsx:146

  • Indexing into USAGE_EXAMPLES assumes it stays perfectly in sync with s.usage.examples; if they ever diverge, this will throw at runtime. Optional chaining with a safe fallback avoids a hard crash while still rendering the text content.
                <CodeBlock
                  code={USAGE_EXAMPLES[index].code}
                  filename={USAGE_EXAMPLES[index].filename}
                />
  • Files reviewed: 27/31 changed files
  • Comments generated: 1
  • Review effort level: Lite

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

Comment thread website/tsconfig.json
Comment on lines +15 to +18
"incremental": true,
"paths": {
"@/*": ["./*"]
},
@umsungjun
umsungjun merged commit e2220c1 into main Aug 6, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants