Engineering a Winning Pitch: Building an Interactive Deck with Next.js 16
🇰🇷 Key Takeaways (요약)
현대적인 피칭을 위한 기술적 도전과 성취:
- Web-based Interactive Deck: 정적인 PDF를 넘어, URL 공유만으로 즉시 접근 가능한 반응형 웹 슬라이드를 구축했습니다. (Next.js 16 + Embla Carousel)
- Context-Aware Mobile UX: 데스크탑에서는 가로형 캐러셀, 모바일에서는 "랜딩 페이지" 스타일의 세로 스크롤로 자동 전환되는 적응형 UI를 구현했습니다.
- Data Storytelling:
Recharts를 활용해 복잡한 K-Beauty 시장 데이터를 직관적인 애니메이션 차트로 시각화했습니다. - Detail-Oriented Engineering: 'Soft Break' 문제 해결부터 SEO 최적화, 다크 모드 툴팁까지, 디테일한 사용자 경험(UX)을 놓치지 않았습니다.
1. Introduction: Beyond the PDF
In the fast-paced world of startup pitching, the medium is often as important as the message. We faced a critical question: "How can we effectively communicate our data-driven K-Beauty solution to global partners like L'Oréal?"
Traditional PDFs are static and lifeless. They fail to convey the dynamic nature of our AI-powered insights.
We decided to build a "Living Pitch Deck"—a web application that feels like a premium presentation but behaves like a modern app. This post details how we engineered this experience using the latest web technologies.
2. Why we chose Next.js 16 for our Pitch Deck?
The choice of technology was strategic. We needed speed, SEO visibility, and seamless interactivity.
| Feature | PDF / PPT | Next.js 16 Web Deck |
|---|---|---|
| Accessibility | Requires download | Instant Link Access |
| Responsiveness | Static (Pinch to zoom) | 100% Mobile Optimized |
| Updates | Resend file | Real-time Deploy |
| Analytics | None | Full GA4 Tracking |
Using Next.js 16 (App Router) allowed us to leverage Server Components for initial load speed while using Client Components for rich interactions like charts and carousels.
3. Solving the "Mobile Context" Problem
Pitch decks are often reviewed on the go—in taxis, waiting rooms, or between meetings. A horizontal slide layout works on a laptop but is a nightmare on a phone.
We implemented a "Hybrid Layout Strategy":
- Desktop (>768px): Horizontal Carousel (Embla) with keyboard & mouse wheel navigation.
- Mobile (<768px): Vertical "Landing Page" Scroll for natural reading flow.
// components/pitch-deck/PitchDeckContainer.tsx
export default function PitchDeckContainer() {
const isMobile = useMediaQuery('(max-width: 768px)');
if (isMobile) {
// Render as a vertical scrollable list
return (
<div className="flex flex-col w-full min-h-screen bg-white">
{SLIDE_DATA.map((slide) => (
<SlideComponent key={slide.id} data={slide} />
))}
</div>
);
}
// Render as an interactive carousel for desktop
return (
<div className="embla" ref={emblaRef}>
{/* Carousel Logic */}
</div>
);
}This ensures that no matter where the investor is, they get the best possible reading experience.
4. How to make data memorable with Recharts?
"Data is boring unless it tells a story."
For 'Beauty Insight Lab', our core value is data. We needed to show, not just tell, how much time and money our AI saves. We used Recharts to bring static numbers to life.
Dynamic Interaction
We added entry animations (animationDuration={2000}) and custom tooltips that react to user hover. This makes the data feel "alive."
// components/pitch-deck/slides/Slide5_Traction.tsx
<BarChart data={data} layout="vertical">
<Tooltip
cursor={{ fill: 'transparent' }}
contentStyle={{ borderRadius: '10px', borderColor: '#eee' }}
formatter={(value: any) => [`${value} Days`, 'Duration']}
/>
<Bar
dataKey="time"
data={data}
isAnimationActive={true}
animationDuration={2000} // Smooth entry animation
>
{data.map((entry, index) => (
<Cell key={`cell-${index}`} fill={entry.fill} />
))}
</Bar>
</BarChart>The result? A chart that visually demonstrates reducing a process from 30 days to 1 day in a way that sticks in the viewer's mind.
5. Overcoming Technical Hurdles (Q&A)
Q: "Markdown text was merging into one line. How did you fix it?"
We encountered an issue where Markdown "Soft Breaks" (single newlines) were being ignored by the browser, rendering distinct lines as a single paragraph.
Solution:
We utilized Tailwind CSS's whitespace-pre-wrap class on the container to force the browser to respect newline characters from the source. We also ensured the remark-breaks plugin was correctly configured in our MDX pipeline.
Q: "We saw 'Duplicate Key' errors in the Table of Contents. Why?"
Our extractHeadings helper was generating IDs simply by slugifying text. When multiple headers had the same text (e.g., "Overview"), it created duplicate IDs, causing React reconciliation errors.
Fix:
We implemented a frequency map to append a counter to duplicate IDs (e.g., overview, overview-1), ensuring every DOM element has a unique identity.
// Helper logic in page.tsx
if (idMap.has(id)) {
const count = idMap.get(id)! + 1;
idMap.set(id, count);
id = `${id}-${count}`; // Make unique
}6. Refactoring for "Beauty Insight Lab"
Branding consistency is key. We performed a comprehensive codebase refactor to remove legacy benchmarking references and unify everything under our own identity, Beauty Insight Lab.
This wasn't just a find-and-replace job; it involved updating asset paths, UI badges, and even PDF filename logic to ensure a seamless, professional brand experience.
This project is part of our journey to expand K-Beauty globally using AI.
We are building more than just a deck; we are building the infrastructure for the future of beauty exports.
Interested in our technology? Check out our Technical Blog.
Beauty Insight Editor
Sharing insights on K-Beauty trends and data-driven export strategies. We help brands expand globally with the power of AI.