요약
무료 Nexoply 계정을 만들고 대시보드의 챗봇 페이지에서 챗봇 키를 복사하세요. App Router에서는 app/layout.tsx의 <body> 안에 next/script의 <Script src="https://nexoply.com/widget.js" data-chatbot={key} strategy="afterInteractive" />를 추가하고, Pages Router에서는 같은 <Script>를 pages/_app.tsx에 넣으세요. 설치할 npm 패키지는 없어요. 위젯은 브라우저에서만 실행되고, 클라이언트 측 이동 중에도 대화를 유지하며, 마크업을 건드리지 않으므로 하이드레이션 문제가 생기지 않아요.
- npm 패키지 없음: 루트 레이아웃(App Router)이나 _app(Pages Router)에 next/script 태그 하나, 또는 이를 감싼 작은 <Chatbot /> 컴포넌트만 넣으면 돼요.
- 키는 NEXT_PUBLIC_NEXOPLY_KEY에 보관하세요. 비밀이 아닌 공개용 키이고, 계정에 접근할 수 없어요.
- strategy="afterInteractive"(기본 선택)를 쓰거나, 다른 모든 것이 로드된 뒤에 불러오려면 "lazyOnload"를 쓰세요.
- SSR에서도 안전: 브라우저에서만 실행되고, document.body의 Shadow DOM에 마운트되며, 라우트가 바뀌어도 유지돼요.
- window.dispatchEvent(new Event("nexoply:open-chat"))로 직접 만든 버튼에서 채팅을 열 수 있어요.
시작하기 전에
- Nexoply 계정. 무료로 가입하세요. 무료 플랜에는 월 대화 50건이 포함되고 카드가 필요 없어요.
- Nexoply에 입력한 비즈니스 정보: 서비스와 가격, 자주 묻는 질문, 정책, 영업시간, 서비스 지역이에요. 가장 빠른 방법은 웹사이트 주소를 입력해 Nexoply가 공개 페이지(JavaScript로 렌더링된 페이지 포함)를 가져오게 하는 거예요. 제안을 검토하고, 승인하기 전에는 아무것도 추가되지 않아요.
- 챗봇 키. 대시보드에서 챗봇을 여세요(아직 만들지 않았다면 챗봇 만들기를 클릭하세요). 그곳의 설치 코드에서 data-chatbot 속성에 키가 들어 있어요.
일반 HTML 사이트라면 설치 코드를 </body> 앞에 붙여 넣기만 하면 돼요.
<script src="https://nexoply.com/widget.js" data-chatbot="YOUR-KEY" async></script>Next.js에서는 HTML을 직접 수정하지 않으므로, 기본 제공 next/script 컴포넌트로 같은 스크립트를 추가해요. 키는 공개용이에요. 위젯이 어느 비즈니스에 속하는지만 알려 줘요.
App Router: app/layout.tsx에 스크립트 추가하기
루트 레이아웃은 모든 페이지를 감싸므로, 여기에 스크립트를 추가하면 사이트 전체에 채팅이 표시돼요. next/script에서 Script를 import하고 <body> 안의 {children} 뒤에 넣으세요.
// app/layout.tsx
import Script from "next/script";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{children}
{/* Nexoply 채팅 위젯: 하이드레이션 후 브라우저에서 로드돼요 */}
<Script
src="https://nexoply.com/widget.js"
data-chatbot={process.env.NEXT_PUBLIC_NEXOPLY_KEY}
strategy="afterInteractive"
/>
</body>
</html>
);
}그런 다음 키를 환경 변수에 넣으세요. NEXT_PUBLIC_ 접두사를 붙이면 Next.js가 브라우저 번들에 값을 포함하는데, 이 키는 비밀이 아니므로 문제없어요.
# .env.local (git에 커밋하지 않아요)
NEXT_PUBLIC_NEXOPLY_KEY=YOUR-KEYPages Router: pages/_app.tsx에 스크립트 추가하기
Pages Router에서는 pages/_app.tsx가 모든 페이지를 감싸므로, 같은 <Script>를 <Component {...pageProps} /> 옆에 넣으세요. .env.local 변수도 똑같이 사용해요.
// pages/_app.tsx
import type { AppProps } from "next/app";
import Script from "next/script";
export default function App({ Component, pageProps }: AppProps) {
return (
<>
<Component {...pageProps} />
<Script
src="https://nexoply.com/widget.js"
data-chatbot={process.env.NEXT_PUBLIC_NEXOPLY_KEY}
strategy="afterInteractive"
/>
</>
);
}프로젝트에서 두 라우터를 함께 쓴다면 app/layout.tsx와 pages/_app.tsx 모두에 스크립트를 추가하세요. 두 번 로드되어도 문제없어요. 위젯은 챗봇 키당 한 번만 마운트돼요.
선택 사항: 재사용할 수 있는 <Chatbot /> 컴포넌트
React 챗봇 컴포넌트 가이드처럼 <Chatbot /> 컴포넌트를 선호하나요? Script를 별도 파일로 옮기세요. next/script는 onLoad 같은 이벤트 핸들러를 넘기지 않는 한 Server Component에서도 작동하므로, 이 파일에는 "use client"가 필요 없어요.
// components/Chatbot.tsx
import Script from "next/script";
export function Chatbot() {
return (
<Script
src="https://nexoply.com/widget.js"
data-chatbot={process.env.NEXT_PUBLIC_NEXOPLY_KEY}
strategy="afterInteractive"
/>
);
}그런 다음 app/layout.tsx의 <body> 안에서 {children} 뒤에, 또는 pages/_app.tsx의 <Component {...pageProps} /> 옆에 <Chatbot />을 렌더링하세요. 모든 라우트에서 로드되도록 단일 페이지가 아니라 레이아웃에서 렌더링하세요.
strategy 선택과 작동 방식
strategy="afterInteractive"는 페이지가 상호작용 가능해진 직후 위젯을 로드하므로 채팅 버튼이 빨리 나타나요. strategy="lazyOnload"는 브라우저가 유휴 상태가 되고 다른 모든 것이 로드될 때까지 기다려요. 첫 로드를 최대한 가볍게 유지하고 싶고, 버튼이 조금 늦게 나타나도 괜찮다면 이쪽을 고르세요. 두 방식 모두 스크립트를 중요 렌더링 경로에서 제외해요. 자세한 내용은 next/script 문서를 참고하세요.
- 클라이언트 측 내비게이션. 방문자가 <Link>나 라우터로 페이지를 이동하는 동안 위젯은 대화를 열어 둔 채 유지하고, URL이 바뀌면 페이지 규칙을 다시 확인해요. 추가 코드는 필요 없어요.
- SSR과 하이드레이션에서 안전. 브라우저에서만 실행되고 React가 하이드레이션하는 마크업 밖의 document.body에 마운트되므로, 하이드레이션 불일치를 일으키지 않아요.
- Shadow DOM. Tailwind나 전역 CSS가 채팅에 스며들지 않고, 채팅의 스타일도 앱에 스며들지 않아요. 리렌더링으로 제거되지도 않아요.
- StrictMode와 Fast Refresh. 개발 환경에서 이펙트가 두 번 실행되거나 핫 리로드가 일어나도 채팅이 두 개 생기지 않아요. 키당 한 번만 마운트돼요.
- 저장소. 쿠키를 설정하지 않아요. 익명 방문자 ID에는 localStorage를, 현재 대화에는 sessionStorage를 사용해요.
Next.js 챗봇, 직접 만들까 호스팅형을 쓸까
Next.js에서는 챗봇을 직접 만들기가 어렵지 않고, 때로는 그게 맞는 선택이에요. 두 방식은 서로 다른 용도에 맞아요.
- 직접 만들기: 채팅 UI 라이브러리나 자체 컴포넌트에, 내 API 키로 AI 모델을 호출하는 route handler나 API route를 더해요. 답변의 근거가 되는 콘텐츠, 대화 저장, 악용 방지도 직접 책임져야 해요. 채팅이 제품의 일부일 때, 예를 들어 사용자 자신의 데이터를 다루는 어시스턴트라면 잘 맞아요.
- 호스팅형 AI 챗봇인 Nexoply는 UI, AI, 백엔드를 함께 제공해요. 추가하거나 가져온 비즈니스 정보(서비스와 가격, 자주 묻는 질문, 정책, 영업시간)로만 방문자의 질문에 답하고, 모르는 내용은 모른다고 말해요. AI 키도 없고 내 서버에서 실행되는 것도 없으며, 대화, 답하지 못한 질문, 스팸 방지는 대시보드에서 관리해요. 비즈니스에 관한 질문에 답해야 하는 고객용 웹사이트에 잘 맞아요.
인터페이스와 모델을 완전히 제어하고 싶다면 직접 만드세요. 백엔드를 운영하지 않고 방문자의 질문에 답하는 것이 목표라면 호스팅형 위젯이 훨씬 수월해요. Nexoply가 비즈니스 정보로 답하는 방식을 확인해 보세요.
직접 만든 버튼에서 채팅 열기
히어로나 가격 섹션에 "채팅으로 문의하기" 버튼을 두고 싶나요? window에서 nexoply:open-chat 이벤트를 발생시키세요. onClick을 쓰므로 클라이언트 컴포넌트여야 해요.
"use client";
// components/ChatButton.tsx
export function ChatButton() {
return (
<button
type="button"
// Nexoply 채팅 창을 열어요
onClick={() => window.dispatchEvent(new Event("nexoply:open-chat"))}
>
채팅으로 문의하기
</button>
);
}<ChatButton />은 어떤 페이지나 서버 컴포넌트에서도 쓸 수 있어요. 위젯은 한 번 로드되면 제거하는 API가 없어요. 일부 페이지(예: /checkout)에서 메시지 버튼을 숨기려면 챗봇 → 맞춤 설정 → 메시지 버튼 → 일부 페이지에서 다르게에서 "버튼 없음" 페이지 규칙을 추가하세요.
로컬 테스트, 허용된 웹사이트, CSP
next dev를 실행하고 http://localhost:3000을 열면 모서리에 채팅 버튼이 나타나요. "주말에도 영업하나요?" 같은 실제 질문을 해 보세요. 몇 초 안에 대시보드의 대화에 그 대화가 표시돼요. 대시보드에서 바꾼 내용은 다시 배포하지 않아도 약 1분 안에 사이트에 반영돼요.
앱이 Content-Security-Policy 헤더를 보낸다면(예: middleware나 next.config에서) 다음 항목에서 Nexoply를 허용하세요.
- script-src https://nexoply.com: widget.js를 로드하기 위해 필요해요.
- connect-src https://nexoply.com: 채팅 요청에 필요해요.
- img-src https://nexoply.com: 로고와 버튼 아이콘 같은 이미지에 필요해요.
문제 해결과 다음 단계
- 버튼이 없고 페이지 소스에서 data-chatbot이 비어 있어요. 환경 변수를 읽지 못한 거예요. NEXT_PUBLIC_ 접두사를 확인하고 next dev를 다시 시작하세요. 호스팅 환경에서는 변수를 추가하고 다시 배포하세요.
- 스크립트가 레이아웃이 아니라 단일 페이지에 있어요. 모든 라우트에서 로드되도록 app/layout.tsx나 pages/_app.tsx에 넣으세요.
- 태그가 바뀌었어요. 태그에는 data-chatbot 속성과 widget.js가 포함된 src가 있어야 해요.
- CSP나 허용된 웹사이트에 막혔어요. 브라우저 콘솔에서 오류를 찾아보고, 위의 두 섹션을 확인하세요.
- 챗봇이 꺼져 있어요. 챗봇 사용 스위치가 켜져 있는지 확인하세요.
- 광고 차단기. 드물게 확장 프로그램이 채팅 위젯을 차단해요. 확장 프로그램이 없는 시크릿 창에서 시도해 보세요.
작동하는 것을 확인했다면 챗봇 → 맞춤 설정에서 사이트에 어울리게 다듬으세요. 버튼 아이콘, 라벨, 색상, 위치를 바꾸거나 화면 가장자리에 사이드 탭(예: "도움말")을 둘 수 있고, 휴대폰에서는 다른 디자인을, 선택한 페이지에는 페이지 규칙(예: /pricing에서만 사이드 탭 표시)을 적용할 수 있어요. 모든 맞춤 설정 옵션과 어시스턴트가 비즈니스를 배우는 방식을 확인하고, 플랜과 대화 한도를 비교하거나 React 챗봇 컴포넌트 가이드와 Vue·Nuxt 챗봇 가이드도 읽어 보세요.
자주 묻는 질문
Next.js용으로 미리 만들어진 React 챗봇 컴포넌트가 있나요?
공식 npm 패키지나 컴포넌트 라이브러리는 없고, 필요하지도 않아요. 이 가이드의 <Chatbot /> 컴포넌트는 next/script를 감싼 몇 줄짜리 코드로, 내 프로젝트에 복사해서 쓰면 돼요. 위젯은 항상 data-chatbot 속성이 있는 https://nexoply.com/widget.js 스크립트이고, 모든 설정은 Nexoply 대시보드에 있어요.
클라이언트 측 이동 중에도 채팅이 유지되나요?
네. 방문자가 <Link>나 라우터로 페이지를 이동하는 동안 대화가 유지되고, URL이 바뀌면 페이지 규칙을 다시 확인해요. 추가 코드는 필요 없어요. 위젯은 레이아웃 밖의 document.body에 있으므로 라우트가 바뀌어도 사라지지 않아요.
Vercel에서도 작동하나요?
네. 방문자의 브라우저에서 로드되는 스크립트 태그일 뿐이에요. 내 서버에서 실행되는 것이 없고, 추가할 API route나 서버 설정도 없어요. Vercel 프로젝트의 환경 변수에 NEXT_PUBLIC_NEXOPLY_KEY를 설정하고 다시 배포하세요.
Core Web Vitals나 성능에 영향을 주나요?
영향을 주지 않도록 설계되어 있어요. 스크립트는 하이드레이션 후(afterInteractive)나 브라우저가 유휴 상태일 때(lazyOnload) 비동기로 로드되므로 렌더링을 막지 않고, 페이지 레이아웃 밖에 마운트돼요.
App Router와 Pages Router 중 무엇을 써야 하나요?
프로젝트에서 이미 쓰고 있는 쪽을 쓰세요. 위젯은 두 라우터에서 똑같이 작동해요. App Router는 app/layout.tsx, Pages Router는 pages/_app.tsx예요.
쿠키 동의 후에만 로드할 수 있나요?
네. 방문자가 동의한 뒤에만 <Script>를 렌더링하세요. 예를 들어 동의 상태를 확인하는 클라이언트 컴포넌트에서 렌더링하면 돼요. 위젯 자체는 쿠키를 설정하지 않아요.
