V2EX 13小时前
[分享创造] Claude code 30 分钟做了一个 Kimi k2 免费套壳站
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文档详细阐述了如何构建一个针对“kimi k2”的AI聊天网站的落地页。内容涵盖了市场调研、页面结构设计、SEO优化、用户体验、以及后端API的搭建,并提供了完整的技术栈和代码示例。通过Next.js、Tailwind CSS、shadcn/ui等技术,实现高性能、用户友好的网站,并提供快速部署的教程。

💡 **市场调研与分析**: 针对“kimi k2”进行SERP分析,提取关键卖点、长尾关键词,优化标题和描述,为网站SEO奠定基础。

🎨 **页面结构与设计**: 采用Next.js 14和Tailwind CSS,构建包括Hero、Features、How It Works、Testimonials、Pricing、FAQ和Footer在内的完整落地页,并支持深色模式。

⚙️ **核心功能实现**: 通过shadcn/ui构建可复用组件,实现动态定价、CTA邮箱订阅API,并支持Prisma数据库存储用户数据,提供数据存储方案。

🚀 **SEO优化**: 动态生成``和`<meta name="description">`,使用JSON-LD进行结构化数据标记,并支持OG标签,提升搜索引擎可见性。</p> </div> <div id="content"> <p>网站:<a href="https://kimik2.ai" rel="nofollow">https://kimik2.ai</a>快来体验,欢迎吐槽 🙏</p><p>Prompt 如下:You are an elite <strong>full-stack engineer & SEO copywriter</strong>. Build a production-ready landing page for <strong><a href="http://kimik2.ai" rel="nofollow">kimik2.ai</a></strong> targeting <strong>“kimi k2”</strong> and featuring the product type <strong>ai-chat</strong>.</p><p><strong>Tech Stack</strong></p><ul><strong>Next.js 14 (App Router, RSC)</strong> — TypeScript, Edge-ready.<strong>Tailwind CSS v3</strong> — dark mode class strategy, custom config.<strong>shadcn/ui</strong> — reusable primitives, including <code>Button</code>, <code>Card</code>, <code>Tabs</code>, <code>Accordion</code>, <code>Dialog</code>, <code>Toaster</code>.<strong>lucide-react</strong> — icon set.Optional: <strong>Prisma + SQLite</strong> for email capture.</ul><h2>1 · Market & SERP Research</h2><ol>Crawl top 10 SERP results for <em>“kimi k2”</em> (EN + ZH)。Summarise: value props, CTA patterns, content gaps, avg. title/meta length.Extract:<ul>3 unique selling points for our page.5 long-tail keywords (≥ 4 words).Best-fit <code><title></code> (≤ 60 chars) & meta description (≤ 155 chars).</ul></ol><p>Return a <strong><code><a href="http://research.md" rel="nofollow">research.md</a></code></strong> with these findings.</p><h2>2 · Landing Page — <code>src/app/page.tsx</code></h2><p><strong>Sections</strong></p><ol><strong>Hero</strong> — H1 (includes kimi k2) + sub-title + primary CTA.<strong>Features</strong> — 3-4 cards (<code>Card</code>) each with icon + headline + copy.<strong>How It Works</strong> — <code>Tabs</code> step-by-step walkthrough with illustrations.<strong>Testimonials</strong> — 3 quotes (<code>Card</code> grid).<strong>Pricing</strong> — dynamic tiers (see rules ↓).<strong>FAQ</strong> — 5-6 questions (<code>Accordion</code>).<strong>Footer</strong> — links + copyright + social.</ol><p><strong>Pricing Rule</strong></p><ul>If <code>{{PRODUCT_TYPE}}</code> == <code>ai-video</code>: tiers <strong>Basic / Pro / Studio</strong>.Else if <code>ai-image</code> or <code>ai-chat</code>: tiers <strong>Starter / Growth / Business</strong>.Use insights from <code><a href="http://research.md" rel="nofollow">research.md</a></code> to set quota & price placeholders.</ul><p><strong>SEO</strong></p><ul>Dynamic <code><title></code> & <code><meta name="description"></code> via <code>generateMetadata()</code>.JSON-LD: <code>BreadcrumbList</code> & <code>Product</code>.OG tags (<code>og:title</code>, <code>og:description</code>, <code>og:image</code>, <code>twitter:card</code>).Sitemap & <code>robots.txt</code> via Next.js route handlers.</ul><p><strong>UX / UI</strong></p><ul>Tailwind palette <code>slate</code> + accent <code>indigo</code>.Light & dark modes (<code>class</code> strategy, respect system).Motion: <code>framer-motion</code> fade-in on section viewport.Accessibility: all interactive components with ARIA labels.</ul><h2>3 · CTA Email Capture API — <code>src/app/api/subscribe/route.ts</code></h2><ol>Accept <code>{ email }</code> POST (JSON).Server action validates & writes to <code>prisma.subscriber</code> (SQLite).Return <code>{ success: true }</code>.Front-end: <code>Dialog</code> → email form → <code>toast</code> on success/fail.</ol><p>Prisma schema:</p><pre><code class="language-prisma">model Subscriber { id Int @id @default(autoincrement()) email String @unique createdAt DateTime @default(now())}</code></pre><blockquote><p>若不想引入数据库,可改存入 SendGrid / Resend / Supabase — 请在 README 备注替代方案。</p></blockquote><h2>4 · Project Bootstrap (可选—已完成可跳过)</h2><blockquote><p><strong>提示</strong>:你已完成此步骤,可直接跳过。如果需要重新初始化项目,请参考下方命令或附录 B 。</p></blockquote><pre><code class="language-bash"># 1. Scaffoldpnpm create next-app@latest kimik2.ai --ts --tailwind --eslint --appcd kimik2.ai# 2. Install depspnpm add @shadcn/ui clsx lucide-react framer-motionpnpm add -D prisma @prisma/client tailwind-merge tailwindcss-animate# 3. Init shadcn/uipnpm dlx shadcn-ui@latest init -y# 4. Generate shadcn components as neededpnpm dlx shadcn-ui@latest add button card tabs accordion dialog toaster# 5. Prisma setup (optional)pnpm dlx prisma init --datasource-provider sqlite</code></pre><h2>5 · Recommended File Tree</h2><pre><code>/ (repo root)├─ src/│ ├─ app/│ │ ├─ page.tsx # landing page (RSC)│ │ ├─ layout.tsx # base <html>│ │ ├─ api/│ │ │ └─ subscribe/│ │ │ └─ route.ts # POST handler│ │ └─ sitemap.xml/route.ts # dynamic sitemap│ ├─ components/│ │ ├─ hero.tsx│ │ ├─ feature-card.tsx│ │ ├─ pricing-table.tsx│ │ └─ ...│ └─ lib/│ └─ prisma.ts├─ prisma/│ └─ schema.prisma├─ public/│ └─ og-default.png├─ README.md└─ tailwind.config.ts</code></pre><h2>6 · Delivery Format</h2><ul>Output <strong>file path → code</strong> in one Markdown block (use <code>tsx`, </code>ts`, etc.).Boilerplate 可用 <code>// ...</code> 占位;关键逻辑需完整。最后附 "🚀 Quick Start" 教程:5 分钟本地运行 + Vercel 部署。</ul><hr /><h3>7 · Grading Checklist (自检)</h3><ul><input disabled="" type="checkbox" /> Lighthouse > 95 (Performance / Best Practices / SEO).<input disabled="" type="checkbox" /> CLS & LCP 分别 < 0.1 和 2 s 。<input disabled="" type="checkbox" /> 页面所有文本包含 kimi k2 的频率控制在 1.5–2.5%。<input disabled="" type="checkbox" /> <code>npm run lint</code> & <code>npm run type-check</code> 无错误。</ul> <div id="recommend_bottom"></div><div id="article_bottom"></div><p id="ID_disclaimer" style="text-align:center;color:#666;font-size:10px;"></p> </div> </div> <div class="extension-group"> <a class="extension-wrap" href="https://web.fishaiapp.com/" title="Fish AI Reader" target="_blank"> <div class="extension-main"> <div class="logo-wrap" style="background-image: url(https://api.rss.fishai.com.cn/static/images/long_only_1x.png);">Fish AI Reader</div> <div class="extension-info"> <h2 class="extension-name"> Fish AI Reader </h2> <p class="extension-desc"> AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。 </p> </div> </div> </a> <div class="extension-wrap"> <div class="extension-main"> <img class="logo-wrap" alt="FishAI" src="/static/image/mini.jpg" /> <div class="extension-info" style="position: relative;"> <wx-open-launch-weapp username="gh_f7703f8c8e64" path="/pages/home/index" style="position: absolute; width: 100%; height: 100%; top: 0px; left: 0px; z-index: 2;"> <script type="text/wxtag-template"> <style> .open-weapp-extension-btn { width: 100%; height: 100%; } </style> <div href="javascript:;" class="open-weapp-extension-btn"></div> </script> </wx-open-launch-weapp> <h2 class="extension-name"> FishAI </h2> <p class="extension-desc"> 鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑 </p> </div> </div> </div> <div class="extension-wrap"> <div class="extension-main"> <div class="extension-info" style="position: relative;"> <wx-open-launch-weapp username="gh_f7703f8c8e64" path="/pages/home/index" style="position: absolute; width: 100%; height: 100%; top: 0px; left: 0px; z-index: 2;"> <script type="text/wxtag-template"> <style> .open-weapp-extension-btn { width: 100%; height: 100%; } </style> <div href="javascript:;" class="open-weapp-extension-btn"></div> </script> </wx-open-launch-weapp> <h2 class="extension-name"> 联系邮箱 <a href="mailto:441953276@qq.com">441953276@qq.com</a> </h2> </div> </div> </div> </div> <div class="article_more"> <h2 class="article_more_title">相关标签</h2> <a href="/tag/kimi+k2" target="_blank">kimi k2</a> <a href="/tag/AI%E8%81%8A%E5%A4%A9" target="_blank">AI聊天</a> <a href="/tag/Next.js" target="_blank">Next.js</a> <a href="/tag/SEO" target="_blank">SEO</a> </div> <div class="share-box"></div> <div id="downTips_end" class="none"> </div> <div class="cb"></div> <div id="relateArea"> <div class="top-liubai"></div> <div class="common_top">相关文章</div> <div id="top5"> <div class="relate_wrapper"> <div class="relate article"> <a title="谷歌意外泄露内部文档,被指欺骗 SEO 行业多年" href="/news/51327"><span class="relate-title"><div class="topic-title">谷歌意外泄露内部文档,被指欺骗 SEO 行业多年</div></span></a></div> <div class="relate article"> <a title="Show HN: Chatty - 用于在浏览器中运行 LLM 的免费人工智能私人聊天工具" href="/news/59407"><span class="relate-title"><div class="topic-title">Show HN: Chatty - 用于在浏览器中运行 LLM 的免费人工智能私人聊天工具</div></span></a></div> <div class="relate article"> <a title="Show HN: 构建模块化前端:使用 React 和 Next.js 的 POC" href="/news/59858"><span class="relate-title"><div class="topic-title">Show HN: 构建模块化前端:使用 React 和 Next.js 的 POC</div></span></a></div> <div class="relate article"> <a title="Show HN: 我创建了一个库,可将 Next.js 应用程序静态托管在 S3/CloudFront 上" href="/news/63227"><span class="relate-title"><div class="topic-title">Show HN: 我创建了一个库,可将 Next.js 应用程序静态托管在 S3/CloudFront 上</div></span></a></div> <div class="relate article"> <a title="Show HN: 在被 LegalZoom 骗局之后,我用 Next.js 构建了自己的产品" href="/news/65278"><span class="relate-title"><div class="topic-title">Show HN: 在被 LegalZoom 骗局之后,我用 Next.js 构建了自己的产品</div></span></a></div> <div class="relate article"> <a title="零成本搭建现代博客之SEO优化篇" href="/news/74027"><span class="relate-title"><div class="topic-title">零成本搭建现代博客之SEO优化篇</div></span></a></div> <div class="relate article"> <a title="什么是SEO" href="/news/74028"><span class="relate-title"><div class="topic-title">什么是SEO</div></span></a></div> <div class="relate article"> <a title="优惠券项目小结" href="/news/74040"><span class="relate-title"><div class="topic-title">优惠券项目小结</div></span></a></div> <div class="relate article"> <a title="大多数时候,SEO马拉松,是持久战,但也有些关键词,只要你上线网站了,就很快几天内就可以收到正反馈。 怎么做到的? 看图二你就知道了,每天这么多新的搜索需..." href="/news/104658"><span class="relate-title"><div class="topic-title">大多数时候,SEO马拉松,是持久战,但也有些关键词,只要你上线网站了,就很快几天内就可以收到正反馈。 怎么做到的? 看图二你就知道了,每天这么多新的搜索需...</div></span></a></div> <div class="relate article"> <a title="前几天做了个新站,最近谷歌日UV都突破了1000,记录下自己的一点点想法 1. 选择比努力更重要 这个站起量起得比较快,并不是因为SEO和推广做得多到位,也不是我网..." href="/news/119643"><span class="relate-title"><div class="topic-title">前几天做了个新站,最近谷歌日UV都突破了1000,记录下自己的一点点想法 1. 选择比努力更重要 这个站起量起得比较快,并不是因为SEO和推广做得多到位,也不是我网...</div></span></a></div> </div> </div> </div> <style> .footer { width: 100%; /* 原先页面已经预留了空间 */ /* height: 2.3rem; */ position: relative; } .footer.padding-bottom{ padding-bottom: 1.2rem; } .footer .fixed-footer { position: fixed; bottom: 0; left: 0; width: 100%; height: 2.3rem; background-color: #191919; z-index: 100; } .footer.padding-bottom .fixed-footer{ padding-bottom: 1.2rem; } .footer .fixed-footer .flex-content{ position: absolute; top: 0; left: 0; right: 0; bottom: 0; height: 2.3rem; display: flex; box-sizing: border-box; align-items: center; justify-content: space-between; padding:0 .55rem; } .footer .icon-left, .footer .icon-right{ position: absolute; width: .55rem; height: .55rem; top: -0.54rem; } .footer .icon-left{ left: 0; } .footer .icon-left::after{ position: absolute; width: .55rem; height: .55rem; content: ''; bottom: -0.01rem; left: -0.01rem; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABC0lEQVQ4T63TMUrEUBDG8e+L5AYWeQFLC72A17Cw8gYqXkDBTryAoBaWixbWWlor1haW8pKZ4mElFj42I4GNhe6ym82bA/z4w8wQwAqAMRINy7Jcres6JPLAoig2VfU1JbijqnfJQOfcqYgcpwSfRGQrJTiOMa6FEOoUKJ1zBuBIRM5Sgu8isg7geyjaFcLM9lX1IhkIIJDcGHrkv4WTshsR2R1S+RdsrT0RuVwW/QeaWQSwrar3y6DTClvny8zal3zoi84C261HkocictUHnQl2CMnbLMsOvPcfi8BzwQkSzOxEVa/nHf+iYBfnSZ6THFVV5acV9wU7ozGzZ5KPAF6apnnL87z23n/+ADjcghv4tAnCAAAAAElFTkSuQmCC'); background-size: 100% 100%; background-repeat: no-repeat; } .footer .icon-right{ right: 0; } .footer .icon-right::after{ position: absolute; width: .55rem; height: .55rem; content: ''; bottom: -0.01rem; right: -0.01rem; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABC0lEQVQ4T63TMUrEUBDG8e+L5AYWeQFLC72A17Cw8gYqXkDBTryAoBaWixbWWlor1haW8pKZ4mElFj42I4GNhe6ym82bA/z4w8wQwAqAMRINy7Jcres6JPLAoig2VfU1JbijqnfJQOfcqYgcpwSfRGQrJTiOMa6FEOoUKJ1zBuBIRM5Sgu8isg7geyjaFcLM9lX1IhkIIJDcGHrkv4WTshsR2R1S+RdsrT0RuVwW/QeaWQSwrar3y6DTClvny8zal3zoi84C261HkocictUHnQl2CMnbLMsOvPcfi8BzwQkSzOxEVa/nHf+iYBfnSZ6THFVV5acV9wU7ozGzZ5KPAF6apnnL87z23n/+ADjcghv4tAnCAAAAAElFTkSuQmCC'); background-size: 100% 100%; background-repeat: no-repeat; transform: rotateY(180deg); } .footer .flex-content .open-weapp { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 10; opacity: 0; } .footer .flex-content .footer-left, .footer .flex-content .footer-right { position: relative; font-weight: bold; } .footer .flex-content .footer-left{ width: 4.35rem; height: 1.25rem; } .footer .flex-content .footer-left .footer-left-content { position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: flex; align-items: center; color: #D4D4D4; font-size: .65rem; } .footer .flex-content .footer-left .footer-left-content .logo{ width: 1.1rem; height: 1.1rem; background-image: url('http://app.myzaker.com/news/images/logo_icon.png'); background-size: 100% 100%; background-repeat: no-repeat; margin-right: .35rem; border-radius: 50%; } .footer .flex-content .footer-right{ width: 4.38rem; height: 1.25rem; line-height: 1.25rem; display: block; box-sizing: border-box; } .footer .flex-content .footer-right .open-weapp-btn{ position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: #2B2B2B; border-radius: .15rem; color: #D4D4D4; font-size: .65rem; text-align: center; display: block; } </style> <script type="text/javascript" src="http://code.jquery.com/jquery-2.1.4.min.js"></script> <script src="/static/js/web3.js" type="text/javascript"></script> <script type="text/javascript" async="false"> var browser = { versions: (function () { var u = navigator.userAgent.toLowerCase(), isPad = false,isAndroidPad = false,isIpad = false,isMobile = false,isPc = false; if(u.indexOf('')) if(u.indexOf('android') > -1){ if(u.indexOf('mobile') == -1){ isAndroidPad = true; } } if(u.indexOf('ipad') > -1){ isIpad = true; } if(isAndroidPad||isIpad){ isPad = true; }else if((u.indexOf('mobile') > -1 && !isPad ) || (u.indexOf('android') > -1 && !isAndroidPad) || (u.indexOf('phone') > -1)){ isMobile = true; }else{ isPc = true; } return { android: u.indexOf('android') > -1 || u.indexOf('Linux') > -1, iPhone: u.indexOf('iphone') > -1, isPad: isPad, isMobile:isMobile, isPc:isPc, wx:u.toLowerCase().indexOf('micromessenger') > -1, }; })() } var checkInZaker = function(){ if (navigator.appinfo || navigator.userAgent.match(/zaker/ig)) { return true; } return false; } if( location.href.indexOf('mobile=1')<0 && (browser.versions.isPc || browser.versions.isPad) ){ var style = '<style type="text/css">'; style+= 'html{background-color:#f8f8f8;}'; style+= '#body{width:720px;margin:0 auto;background-color:#fff;border-left:1px solid #e8e8e8;border-right:1px solid #e8e8e8;font-style:normal}'; style+= '#temple_title,#content_text,.icon-font-origin,#top5{padding:0 50px;}'; style+= '#downTips{width:720px;}'; style+= '#qrcode{position:fixed;background-color:#fff;margin:44px 0 0 740px;}'; style+= '#downTips{display:none;}'; style+= '</style>'; document.write(style); } var _$ = function(id){return document.querySelector(id);}, isWap = true; var qrcodeHtml = '' if(location.href.indexOf('mobile=1')<0 && browser.versions.isPc){ qrcodeHtml += '<img id="qrcode" src="/static/image/qrcode_dingyuehao.jpg"/>' } qrcodeHtml += '<div class="zk_top_barwrap"><div class="zk_top_bar"><a href="/" class="zk_top_bar_logo"></a></div></div>' $('#body').prepend(qrcodeHtml); </script> <script type="text/javascript"> var new_style = ''; var vo = document.createElement("a"); vo.className = 'icon-font-origin-btn'; vo.style.borderBottom = 'none'; vo.style.color = '#00abff'; vo.style.marginLeft = '0px'; if(new_style){ vo.style.cssText="border-bottom-style: none;font-size: 11px;color: #ababab;margin-left: 6px;"; document.getElementById('ID_disclaimer').style.cssText='text-align: left;color:#ababab;font-size: 16px;line-height: 32px;padding:0;padding-top: 4px;'; } vo.href = 'https://www.v2ex.com/t/1144828#reply2'; vo.innerHTML = '查看原文'; var el_disclaimer = _$("#ID_disclaimer"); if(el_disclaimer){ el_disclaimer.appendChild(vo); } </script> <script type="text/javascript"> //图片初始化 (function () { var imglazy = document.querySelectorAll('.img_box .lazy'); imglazy = Array.prototype.slice.call(imglazy); imglazy.forEach(function(img){ // 获取宽高 var dWidth = img.dataset['width']; var dHeight = img.dataset['height']; // 获取父元素 var parentEle = img; do{ parentEle = parentEle.parentNode; } while(!parentEle.classList.contains('img_box') || parentEle.id == "content") // 获取图片的父容器占宽 var parentWidth = parentEle.offsetWidth; // 1. 图片原宽度大于容器宽度70%,撑到100% // 2. 图片原宽度大于容器宽度40%,小于容器宽度70%,保持图片原尺寸 // 3. 图片原宽度小于容器宽度40%,撑到40% var maxRate = 0.7; var minRate = 0.4; // 计算阀值 var maxWidth = maxRate * parentWidth; var minWidth = minRate * parentWidth; // 最终设定图片的宽高 var imgWidth, imgHeight; if (dWidth) { if (dWidth > maxWidth) { imgWidth = parentWidth; } else if (dWidth > minWidth) { imgWidth = dWidth; img.parentNode.style['display'] = 'inline-block'; // img.parent('.content_img_div').css('display', 'inline-block'); } else { imgWidth = minWidth; img.parentNode.style['display'] = 'inline-block'; // img.parent('.content_img_div').css('display', 'inline-block'); } // 计算高度 imgHeight = dHeight / dWidth * imgWidth; } else { imgWidth = parentWidth; } // 设置图片大小 img.style['width'] = imgWidth + "px"; img.style['height'] = imgHeight + "px"; }); })(); </script> <script> var inzaker = (navigator.userAgent.match(/zaker/ig)) ? true : false; if(!inzaker && !navigator.userAgent.match(/AlipayClient/ig) ){ if(document.querySelector('.ntpl_head')){ (function(){ function getStyle(obj,attr){ if(obj.currentStyle){ return obj.currentStyle[attr]; }else{ return document.defaultView.getComputedStyle(obj,null)[attr]; } } var $ntplHead = document.querySelector('.ntpl_head'), pt = getStyle($ntplHead, 'paddingTop'); $ntplHead.style.paddingTop = (parseInt(pt, 10) - 20)+'px'; })(); } } window.zkgetWebConfig = function(data) { inzaker = true; if(data.appType == 'elderly'){ document.getElementsByTagName('body')[0].className += ' body_elderly'; } }; </script> </body> <!-- Google tag (gtag.js) --> <script async src="https://www.googletagmanager.com/gtag/js?id=G-LT4LDFPVLZ"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-LT4LDFPVLZ'); </script> </html>