AI 资讯
Why Many Frontend Developers Use Next.js for work, but Vue.js for Personal Projects
🇮🇩 Originally written in Indonesian. This English version was AI-assisted and adapted for a more natural reading experience. It is not a literal translation. _open Introduction Lately, I've been having quite a few discussions with frontend developers about the frameworks they use. My question is actually pretty simple. "When you're building a web frontend, what framework do you usually use?" Almost everyone gave more or less the same answer. "It depends on the project." And honestly, I agree. There's no framework that's always the best choice for every situation. However, as the conversation went on, they started sharing their own experiences and preferences. Well... That's when I started noticing an interesting pattern. Among the developers I talked to, quite a few of them mentioned that they usually use Next.js / React for work, while Vue.js is what they often choose for personal projects. The interesting part is... I never actually asked, "What do you use at work?" or "What do you use for personal projects?" That explanation came up naturally as they explained why they preferred certain frameworks. At first, I thought it was just a coincidence. But after hearing the same pattern from several different people... I got curious. Why do so many developers who are comfortable with both frameworks end up separating how they use them? (・_・;) Disclaimer This isn't based on an official survey or research. It's simply an interesting pattern I noticed after talking with several frontend developers. Discussion Vue.js Looking at today's frontend ecosystem, Vue.js is clearly not a small framework. Its community is large. Its documentation is great. Its ecosystem is also quite mature. That said, compared to React and Next.js, its community is still smaller. Then another question comes to mind. If that's the case... Why do so many developers still choose Vue.js for personal projects? From the answers I heard, the main reason wasn't performance. And it wasn't because other framew
AI 资讯
Kenapa Banyak Frontend Developer Memakai Next.js untuk Pekerjaan, tapi Vue.js untuk Personal Project?
Artikel ini juga tersedia dalam bahasa Inggris Pendahuluan Beberapa waktu terakhir saya sering berdiskusi dengan beberapa frontend developer mengenai framework yang mereka gunakan. Pertanyaan saya sebenarnya sederhana. "Kalau membuat frontend web, biasanya pakai framework apa?" Hampir semuanya memberikan jawaban yang kurang lebih sama. "Tergantung kebutuhan." Dan saya setuju. Tidak ada framework yang selalu menjadi pilihan terbaik untuk semua kondisi. Namun, setelah pembahasannya berlanjut, mereka mulai menceritakan pengalaman dan preferensinya masing-masing. Nah... Di sinilah saya mulai menemukan pola yang menarik. Dari beberapa developer yang saya ajak berdiskusi, cukup banyak yang mengatakan bahwa mereka lebih sering menggunakan Next.js / React untuk pekerjaan, sedangkan Vue.js lebih sering digunakan untuk personal project. Padahal saya tidak pernah bertanya, "Kalau kerja pakai apa?" atau "Kalau project pribadi pakai apa?" Penjelasan itu muncul begitu saja ketika mereka mulai menjelaskan alasan di balik framework yang mereka pilih. Awalnya saya mengira itu hanya kebetulan. Tapi setelah mendengar pola yang sama dari beberapa orang... Saya jadi penasaran. Kenapa banyak developer yang sudah menguasai keduanya justru memilih memisahkan penggunaannya? (・_・;) Disclaimer Tulisan ini bukan hasil survei atau penelitian resmi. Ini hanyalah pola yang saya temui dari beberapa frontend developer yang sempat saya ajak berdiskusi. Pembahasan Vue.js Kalau melihat ekosistem frontend saat ini, Vue.js jelas bukan framework yang kecil. Komunitasnya besar. Dokumentasinya bagus. Ekosistemnya juga sudah cukup matang. Namun memang harus diakui, jika dibandingkan dengan React dan Next.js, komunitasnya memang masih lebih kecil. Lalu muncul pertanyaan. Kalau begitu... Kenapa masih banyak yang memilih Vue.js untuk personal project? Dari beberapa jawaban yang saya dengar, ternyata alasan utamanya bukan karena performa. Bukan juga karena framework lain kurang bagus. Melainkan karena pengalama
AI 资讯
Parallel Routes in Next.js App Router — Rendering Multiple Pages in One Layout
Parallel Routes let you render multiple pages simultaneously within the same layout. Instead of navigating away from a page to show another one, you can display both at the same time — a dashboard with independently navigable sections, a main content area alongside a sidebar that changes with its own navigation, or a feed with an openable detail panel that doesn't replace the feed. This is one of the more powerful App Router features and one of the more confusing to set up initially. Here's the complete pattern, including the design approach used for complex multi-panel interfaces like the generation tool at Pixova . The Core Concept — Named Slots Parallel routes use named slots: special folders prefixed with @ that define independent rendering areas within a layout. app/ ├── layout.tsx ← Receives slot props ├── page.tsx ← Default slot content ├── @sidebar/ │ ├── page.tsx ← Sidebar default │ └── settings/ │ └── page.tsx ← Sidebar settings view └── @modal/ ├── page.tsx ← Modal default (null) └── photo/[id]/ └── page.tsx ← Photo modal The layout receives each slot as a prop: // app/layout.tsx export default function Layout ({ children , sidebar , modal , }: { children : React . ReactNode ; sidebar : React . ReactNode ; modal : React . ReactNode ; }) { return ( < div className = "flex h-screen" > < aside className = "w-64 border-r" > { sidebar } </ aside > < main className = "flex-1" > { children } </ main > { modal } </ div > ); } Now children , sidebar , and modal can each navigate independently. Independent Navigation — The Key Behavior Each parallel route slot navigates independently. When a user navigates from / to /settings , the children slot updates. The sidebar slot stays exactly where it was — its navigation state is independent. This is the key difference from nested layouts. Nested layouts rerender from the changed segment outward. Parallel routes don't affect each other. User is at / (children shows home, sidebar shows default nav) User navigates to /setti
AI 资讯
Sanity image-url hotspot not working: four causes and fixes
Sanity's hotspot and crop system works well when all the pieces line up — but if your rendered image is ignoring the focal point you set in Studio, one of four things is almost certainly wrong. None of them are subtle bugs; they're all configuration mistakes that are easy to miss and easy to fix. The four causes (and their fixes) 1. fit is still set to clip instead of crop This is the most common cause. The @sanity/image-url builder defaults to fit('clip') , which scales the image to fit inside the requested dimensions without cropping anything. Hotspot data is only applied when the builder is told to crop — that is, when it cuts the image down to the requested dimensions, centering the cut on the focal point. Fix: always chain .fit('crop') when you pass .width() and .height() . // src/lib/sanity-image.ts import imageUrlBuilder from ' @sanity/image-url ' import { client } from ' ./sanity-client ' const builder = imageUrlBuilder ( client ) export function urlFor ( source : SanityImageSource ) { return builder . image ( source ) } // Usage — hotspot will only apply if fit is 'crop' const url = urlFor ( image ) . width ( 800 ) . height ( 600 ) . fit ( ' crop ' ) // <-- required for hotspot to do anything . auto ( ' format ' ) . url () Without .fit('crop') , Sanity's CDN receives no crop instruction and the hotspot coordinates are silently ignored. 2. Missing options: { hotspot: true } on the schema field If the image field in your Sanity schema is not configured with hotspot support, Studio never renders the focal point UI, and the hotspot and crop keys are never written to the document in the first place. The URL builder can't use data that isn't there. Fix: add options: { hotspot: true } to every image field where editors need focal control. // schemas/post.ts export default { name : ' post ' , type : ' document ' , fields : [ { name : ' coverImage ' , type : ' image ' , options : { hotspot : true , // <-- enables the focal point UI in Studio }, }, ], } After adding
AI 资讯
Sanity vs Directus for Next.js in 2026: An Honest Comparison
Sanity vs Directus is a comparison that comes up more than you'd expect on technical forums in 2026, usually from teams who already have a Postgres database running and are wondering why they'd pay for a separate content lake when Directus can wrap what they have. It's a fair question. These two tools solve adjacent problems but from genuinely different starting points, and the right choice depends heavily on whether your content is primarily relational data or editorial content. What each tool actually is Sanity is a hosted content platform. Your content lives in Sanity's managed "content lake" — a document store with real-time collaboration, a CDN-backed asset pipeline, and GROQ as the query language. You define schemas in code, deploy a customisable Studio, and talk to Sanity's API from your Next.js app. You do not manage infrastructure. Directus is an open-source data platform that wraps any existing SQL database — Postgres, MySQL, SQLite, MS SQL — and exposes it through a REST API, a GraphQL endpoint, and a web-based admin UI. Schema changes happen in the admin UI (or via migrations), and your data stays in your own database. You can self-host entirely or use Directus Cloud. That distinction — hosted content lake vs database-wrapper — drives nearly every practical difference between them. Data ownership and where your content lives With Sanity, your content lives in Sanity's infrastructure. You can export it via the export API, but you are operationally dependent on Sanity's uptime and their CDN. For most product teams that's fine — Sanity has been reliable and their SLA on Growth/Enterprise tiers is solid. But if you're in a regulated industry, have strict data residency requirements, or your client contract requires them to own the database, it's a real constraint. With Directus, the database is yours from day one. You point Directus at a Postgres instance on your own infrastructure (or a managed one like Supabase, Neon, or Railway), and Directus adds the API
AI 资讯
I Built AICostPass Because I Was Tired of Guessing My AI API Costs
While building with OpenAI, Anthropic, and other AI providers, I realized something surprising. I monitored my servers, databases, and application performance—but I had almost no visibility into my AI API spending until I checked the provider dashboard or received the monthly invoice. That led me to build AICostPass . It helps developers, indie hackers, startups, and agencies: ⚡ Track AI API costs in near real time 📊 Monitor spending by project or client 🚨 Get budget threshold email alerts 📧 Receive weekly spending summaries 💰 Export billable CSVs for client invoicing The goal is simple: help developers understand and control AI costs before the invoice arrives. 👉 https://aicostpass.com I'd love to hear how you're currently tracking AI API costs. Are you using provider dashboards, spreadsheets, or another tool?
AI 资讯
Migrating a Vite i18n App to Next.js Without Breaking Everything
The Architecture Shift: SPA vs. Framework Internationalization (i18n) is one of those features that feels straightforward in a Single Page Application (SPA). You install react-i18next , wrap your app in a provider, and you're good to go. However, when you decide to migrate that Vite-based React app to Next.js for better SEO and performance, the strategy for i18n changes fundamentally. In a Vite SPA, i18n is typically client-side. In Next.js, i18n happens at the routing and server level. If you don't plan the migration carefully, you'll end up with hydration mismatches, flashing text, or broken search engine indexing. Here is how to navigate the transition. 1. Defining the Routing Strategy In Vite, your translations often live in the same bundle, and you swap them out using a state hook. Next.js, particularly with the App Router, prefers sub-path routing (e.g., /en/about or /es/about ). This is crucial for SEO because it allows search engines to crawl localized versions of your pages individually. Instead of relying on localStorage to remember a user's language, you should now rely on the URL. Most teams moving from Vite use a middleware approach to detect the user's preferred locale and redirect them to the correct sub-path. 2. Choosing the Right Library If you were using react-i18next in your Vite project, you have two main paths in Next.js: next-i18next (Pages Router): The traditional choice for the Pages Router. next-intl or i18next + i18next-resources-to-backend (App Router): These are modern solutions that leverage Server Components. When handling complex migrations involving many components, using a specialized tool like ViteToNext.AI can help automate the transformation of your Vite project structure into a Next.js-ready architecture, saving you hours of manual refactoring. 3. Handling Server Components vs. Client Components one of the biggest hurdles is that useTranslation() hooks from standard i18n libraries are "Client hooks." In the App Router, you'll wan
AI 资讯
Building an AI-Powered Lead Qualification API with Next.js 15 and Gemini 3.5 Flash
Every business wants more leads. But the real challenge isn't generating them—it's identifying which leads deserve your team's attention first. Instead of manually reviewing every inquiry, we can build a simple AI-powered API that analyzes incoming leads and assigns a priority score automatically. In this article, I'll show a lightweight production-ready approach using Next.js 15 and Gemini 3.5 Flash. Project Structure app/ ├── api/ │ └── qualify/ │ └── route.ts ├── lib/ │ └── gemini.ts └── page.tsx API Route import { NextResponse } from "next/server"; export async function POST(req: Request) { const { company, message } = await req.json(); const prompt = ` Company: ${company} Message: ${message} Give: - Score (1-100) - Priority - Reason `; // Call Gemini API here return NextResponse.json({ success: true, score: 92, priority: "High" }); } Example Response { " score " : 92 , " priority " : " High " , " reason " : " Large company with a clear automation requirement. " } Now your CRM, chatbot, or automation workflow can instantly decide which leads should be contacted first. Why This Matters A simple AI scoring layer can help teams: Reduce manual lead review Respond faster to high-value prospects Prioritize enterprise customers Improve sales efficiency Save hours every week The best part is that this API can be connected to forms, chatbots, CRMs, or n8n workflows without changing your existing process. Production Tips Before deploying this to production, make sure you: Validate incoming requests Store API keys securely Add rate limiting Log AI responses for monitoring Cache repeated requests where appropriate Small improvements like these make a huge difference once traffic starts growing. Final Thoughts AI shouldn't replace your sales team—it should remove repetitive work so they can focus on conversations that actually matter. A lightweight lead qualification API is one of the fastest AI features you can add to an existing product, and it scales well as your business
AI 资讯
React useOptimistic: Optimistic UI Patterns That Actually Work (2026)
The problem with most web UIs is the gap between user action and visible feedback. A user clicks "like" and waits 200-400ms for the server to respond before the button changes. That delay reads as slowness even when the server is fast. The network round-trip is the ceiling. Optimistic UI inverts this: assume the operation will succeed, update the UI immediately, then reconcile with the server response when it arrives. If the server fails, roll back. React 19's useOptimistic hook gives you this pattern with minimal boilerplate and automatic rollback built in. The API const [ optimisticState , addOptimistic ] = useOptimistic ( state , // the current "real" state — synced from server updateFn , // (currentState, optimisticValue) => newOptimisticState ) optimisticState — during a pending transition, reflects the optimistic update. Once the transition completes, it reverts to state addOptimistic(value) — triggers an optimistic update, must be called inside startTransition Pattern 1: Like Button ' use client ' import { useOptimistic , useTransition } from ' react ' import { toggleLike } from ' @/actions/likes ' type LikeState = { liked : boolean ; count : number } export function LikeButton ({ postId , initialLiked , initialCount }: { postId : string initialLiked : boolean initialCount : number }) { const [ isPending , startTransition ] = useTransition () const [ optimisticState , addOptimistic ] = useOptimistic < LikeState > ( { liked : initialLiked , count : initialCount }, ( current ) => ({ liked : ! current . liked , count : current . liked ? current . count - 1 : current . count + 1 , }) ) function handleToggle () { startTransition ( async () => { addOptimistic ( ' toggle ' ) // updates UI immediately await toggleLike ({ postId }) // syncs with server }) } return ( < button onClick = { handleToggle } disabled = { isPending } > < Heart className = { cn ( ' h-4 w-4 ' , optimisticState . liked && ' fill-red-500 text-red-500 ' ) } /> < span > { optimisticState . count }
AI 资讯
Casting your friend group as a K-Pop group without making a database the product
Try the demo: K-Saju Crew For fun only. K-Saju is an entertainment project. The K-Pop roles below are a playful interpretation of saju-inspired signals, not personality assessment or advice. A two-person compatibility page can stay stateless with almost no effort. Put both birth dates in a URL, render the result on the server, and the link is the record. No account, no database, no cleanup job. That was already a product rule in K-Saju. We do not retain personal inputs. A result is reproducible from its GET parameters. Then we built /crew : “What if your friend group debuted as a K-Pop group?” A creator makes a link, sends it to a group chat, and each friend enters their own birth date. At three to seven members, the app assigns distinct positions, shows pairwise chemistry, and creates a shareable poster. The fun part is the casting. The engineering problem is that the social flow needs a temporary shared state. A link cannot accumulate submissions by itself. This post is about the decisions behind that feature: where we allowed state, how we made the result durable without retaining a lobby forever, and how we kept the casting explainable instead of treating it as a black-box score. The conflict: a self-service group flow needs somewhere to collect data There were two clean but incomplete options. The first was to keep everything stateless. The creator would enter all members' dates at once, then receive a result URL. It matched our existing architecture, but it defeated the point of sharing a link. The person who starts the group often does not know everyone else's date, and asking them to collect it in a chat creates friction before the feature has started. The second was a conventional persistent group object. It would make joining easy, but it would turn a deliberately stateless service into one that keeps user-provided dates indefinitely unless we built retention and deletion policies around it. We chose a hybrid instead: The lobby is temporary state. It store
AI 资讯
I built two Next.js 15 + Tailwind v4 templates with zero extra dependencies — here's what I learned
Earlier this month I shipped two premium templates — a SaaS landing page and a developer portfolio. Not a startup, not a SaaS, just templates. This post is about the two constraints I built them under, why they made the code better, and a few things I learned launching as a solo dev with zero audience. Constraint 1: zero dependencies beyond next, react, and tailwind Open the package.json of most templates and you'll find 20+ packages: icon libraries, animation libraries, carousel plugins, UI kits, utility libraries. Every one of them is a version conflict waiting to happen for the buyer, and most are replaceable with a few lines of code in 2026. What I used instead: Icons → inline SVG components. An icon component is ~10 lines. You need maybe 15 icons for a landing page. Animations → plain CSS. Scroll-blur navbars, gradient glows, an animated "typing" terminal — all doable with keyframes and transitions. No framer-motion. The dashboard mockup in the hero → pure CSS. Divs, borders, gradients. It looks like a product screenshot but it's ~80 lines of JSX and weighs nothing. Result: both templates land at ~100KB first-load JS, npm install takes seconds, and there is nothing to break when Next.js 16 arrives. Constraint 2: every piece of content in ONE typed config file The thing I hated most about templates I've used: content is smeared across 30 components. Changing a headline means hunting through JSX. So both templates keep all content in a single file — lib/content.ts for the landing page, site.config.ts for the portfolio. Headlines, nav, pricing tiers, testimonials, project lists, even the lines that animate in the fake terminal. Components are pure renderers of that config's TypeScript type. Two things surprised me here: TypeScript becomes your content linter. Forget an alt text, malform a link, give a pricing tier three features when the type expects a non-empty array — the build fails. Content mistakes surface at compile time. It forces better component design. W
AI 资讯
What actually crosses the React Server Component boundary
Everyone can type "use client" . Almost nobody can say what survives the trip across it — and then something breaks: next build dies at prerender, the error names no file and no import chain, and the prop that killed it was an arrow one level down inside an object called options . Here's the uncomfortable secret: the boundary is one serializer . React walks every prop you hand a client component, encodes each value it has a branch for, and throws on the first one it doesn't. This post reads those branches out of React 19's Flight source — one file, no framework — and shows the two traps that pass code review and fail the build anyway. What crosses A prop is legal if the serializer has a branch for it. Everything else falls into one prototype check and throws. The whole contract fits on a screen: // app/page.tsx — a Server Component. Every comment is the serializer's verdict. export default function Page () { return ( < Chart title = "Q3" data = { { rows : [ 1 , 2 , 3 ] } } when = { new Date () } seen = { new Set ([ 1 ]) } index = { new Map () } rows = { fetchRows () } // an un-awaited Promise; the client calls use(rows) bytes = { new Uint8Array ( 8 ) } // ArrayBuffer, DataView, every typed array upload = { new File ([], ' a.csv ' ) } // there is no File branch — a File is a Blob form = { new FormData () } stream = { new ReadableStream () } kind = { Symbol . for ( ' chart ' ) } // global symbols cross; Symbol('chart') throws Slot = { Legend } // a client component: a function, and a client reference save = { saveRow } // a "use server" function: a server reference err = { new Error ( ' boom ' ) } // crosses — and arrives empty in production // no branch — every one of these throws at render match = { /q3/ } href = { new URL ( ' https://x.dev ' ) } cache = { new WeakMap () } user = { new User ( ' ada ' ) } bare = { Object . create ( null ) } onPick = { ( id ) => select ( id ) } /> ); } Four of those lines are the ones people get wrong: new Error() crosses, and product
AI 资讯
React Compiler in 2026: What It Actually Memoizes (And What It Doesn't)
Headline: React Compiler — formerly React Forget — shipped stable with React 19 and automatically memoizes components, hooks, and callbacks by analyzing data flow at build time. No dependency arrays to write; the compiler infers them. Here is what it handles, when it opts out, and whether you should delete your useMemo calls. Key takeaways React Compiler inserts useMemo , useCallback , and React.memo automatically at build time — no dependency arrays to maintain. Enable it in Next.js 15/16 with experimental.reactCompiler: true in next.config.ts . The compiler is conservative: if it cannot prove memoization is safe, it emits the component unchanged. "use no memo" is the escape hatch for functions the compiler should not touch. Run npx react-compiler-healthcheck@latest before enabling to see coverage and violations. What does React Compiler actually do? React Compiler transforms component and hook code at build time to insert memoization automatically. Instead of useMemo(() => expensiveCalc(a, b), [a, b]) , the compiler analyzes data flow, determines which values are stable across renders, and emits equivalent memoized code. The compiled output uses React's memo infrastructure at runtime. The compiler is babel-plugin-react-compiler — it works with any Babel-based build pipeline. How do I enable it in Next.js? // next.config.ts const nextConfig = { experimental : { reactCompiler : true , }, }; export default nextConfig ; Before enabling, run the healthcheck: npx react-compiler-healthcheck@latest The healthcheck reports optimizable component count, files with violations, and blocking patterns. Fix violations first for more coverage on day one. What does the compiler memoize? Components — equivalent to React.memo ; re-renders only when props change. Values — equivalent to useMemo ; computed results, derived arrays, objects. Callbacks — equivalent to useCallback : event handlers, functions passed as props. Dependencies are inferred from escape analysis — n
AI 资讯
Partial Prerendering in Next.js: The Static Shell + Dynamic Stream Model
Headline: Partial Prerendering (PPR) in Next.js serves a static HTML shell from the CDN edge instantly, then streams Suspense-wrapped dynamic children from the origin in the same HTTP response. No full-page ISR staleness, no full-page origin latency. I shipped it on two production routes — here is the model. Key takeaways PPR serves a static HTML shell from the CDN edge , then streams dynamic Suspense children from the origin in the same response. The static shell is built at build time — outside <Suspense> renders statically; inside renders dynamically per request. PPR replaces the ISR vs. dynamic tradeoff for pages that are mostly static with isolated personalized sections. No changes to Server Components or Suspense — just experimental.ppr: 'incremental' in config and export const experimental_ppr = true per route. PPR and use cache are complementary : CDN delivery for the shell, origin memoization for dynamic islands. What does PPR actually do? PPR splits a page into two rendering phases within the same HTTP response. At build time, Next.js freezes everything that does not read dynamic request data into a static HTML shell on the CDN edge. At request time, the CDN delivers the shell at edge latency while the origin streams each <Suspense> boundary's content into the same response. On a product page: navigation, title, and description arrive at CDN speed. The in-stock badge and personalized recommendations stream from the origin a fraction of a second later. The user sees a nearly-complete page immediately. How is PPR different from ISR and streaming Suspense? Strategy First byte Dynamic freshness Staleness ISR (revalidate: N) CDN edge Whole page up to N seconds stale Full page Dynamic rendering Origin 100% fresh; waits for slowest query None Streaming Suspense (no PPR) Origin Fresh; TTFB includes origin latency None PPR CDN edge Dynamic islands 100% fresh Static shell only How do I enable PPR? // next.config.ts export default { experimental : { ppr : ' inc
AI 资讯
Server Components vs Client Components: The Mental Model Shift Every Vite Developer Needs
Introduction If you have been building applications using Vite, you are likely used to a specific workflow: write React components, bundle them with esbuild/Rollup, and serve a single HTML file that fetches a large JavaScript bundle. In this world, everything is a "Client Component." However, as the React ecosystem shifts toward the App Router and React Server Components (RSC), the architecture is fundamentally changing. For developers moving from a Vite-centric mindset to a Next.js framework, the biggest hurdle isn't the syntax—it's the mental model. In this guide, we will break down the core differences between Server and Client components and how to adapt your Vite-based habits to this new reality. The Vite World: Single-Page Application (SPA) Default In a standard Vite + React project, your entire application lifecycle happens in the browser. The browser requests the page. The server sends a nearly empty index.html . The browser downloads the JS bundle. React hydrates the app, fetches data from an API via useEffect , and renders the UI. While this is excellent for developer experience (DX) and highly interactive dashboards, it often leads to "Layout Shift" and slower "Time to Interactive" for content-heavy pages because the client has to do all the heavy lifting. The Shift: Thinking in "Environment Splits" With React Server Components, the paradigm shifts from "Everything happens on the client" to "Compute where it makes sense." 1. What are Server Components? By default, in the Next.js App Router, every component is a Server Component. These components execute only on the server . They never send their code to the client-side bundle. This allows you to: Access backend resources directly: You can query your database or file system inside the component. Keep secrets safe: API keys and sensitive logic stay on the server. Reduce bundle size: Large dependencies (like a markdown parser or date library) stay on the server and only the resulting HTML is sent to the user
AI 资讯
The Complete Redbelly EligibilitySDK Integration Guide: Widget to Backend to On-Chain
The Redbelly Network EligibilitySDK is the compliance backbone for any dApp that needs to verify user eligibility (KYC, KYB, investor accreditation) before letting a wallet in. The official documentation covers each piece well on its own reference page, but there is no single walkthrough connecting the frontend widget to the backend verifier to the on-chain permission check to a production deployment. This guide is that walkthrough. Everything here was verified against the live documentation at https://docs.redbelly.network/ in July 2026: contract addresses, route names, config fields, issuer DIDs and every error string in the reference section. Every code example was then compiled against the published SDK package (v0.0.31) on React 19 with Vite and on Next.js 16 with the App Router, and the backend verifier was booted and exercised for real. Where the docs and reality diverge (a quickstart repo that is not publicly visible, a credential faucet still under development, three undocumented behaviours the builds surfaced), the guide says so and gives you the workaround. What you will build, in order: A mental model of the two verification mechanisms (and why conflating them costs you a day) A working backend verifier with the three routes the widget demands A plain React integration with full loading and error states A production-grade Next.js App Router setup: secure proxy, SIWE sessions, request gating, and both static and dynamic rendering approaches An end-to-end test run on Redbelly Testnet The decision logic for choosing between the three SDK flows, and the pattern for combining them A complete error reference: every documented error, its cause, and its fix A developer following this guide should have the widget running inside an existing dApp within about four hours. 1. Overview and Architecture What the EligibilitySDK actually is The Redbelly "Onboarding and Eligibility Kit" ( @redbellynetwork/eligibility-sdk ) is a set of React components and hooks for provin
AI 资讯
How I Structure Large Next.js Projects — Folder Architecture Guide
Bad nextjs folder structure does not show up on day one. It shows up at month six when three developers search for the checkout form hook and find four copies. I reorganised a client dashboard after exactly that — this guide is the tree I use now on large App Router projects, why each folder exists, mistakes from my first Next.js apps, and the 10-second findability rule . Real folder tree — production-shaped layout my-app/ ├── app/ # routes only — thin pages │ ├── (marketing)/ # route group — shared layout, no URL segment │ │ ├── layout.tsx │ │ ├── page.tsx │ │ └── pricing/page.tsx │ ├── (dashboard)/ │ │ ├── layout.tsx │ │ └── orders/page.tsx │ ├── api/ # route handlers │ │ └── webhooks/stripe/route.ts │ ├── layout.tsx # root layout │ └── globals.css ├── components/ # shared UI — buttons, cards, shell │ ├── ui/ │ └── layout/ ├── features/ # business domains — colocated logic │ ├── auth/ │ │ ├── components/ │ │ ├── hooks/ │ │ └── actions.ts │ └── orders/ │ ├── components/ │ ├── api.ts │ └── types.ts ├── lib/ # server + shared utilities │ ├── db.ts │ └── env.ts ├── hooks/ # truly global client hooks ├── types/ # global TS types ├── data/ # static data, blog posts list └── public/ Routes live in app/ . Business logic lives in features/ . Generic design system pieces live in components/ui . That separation is the whole game. Why each folder exists Folder Purpose Do not put here app/ URLs, layouts, loading.tsx Fat business logic features/ Domain modules (orders, auth) Generic Button components/ui Reusable primitives Order-specific tables lib/ DB clients, env validation React components app/api Webhooks, REST edge cases Every form POST (prefer actions) Thin pages — route files under 40 lines // app/(dashboard)/orders/page.tsx — orchestration only import { OrderTable } from "@/features/orders/components/OrderTable"; import { getOrders } from "@/features/orders/api"; export default async function OrdersPage() { const orders = await getOrders(); return ( <section> <h1>Orders
开发者
Next.js vs React in 2026
React is a library, Next.js is a framework — here's what that actually means for your project, and how to choose based on SEO, scale, and team.
AI 资讯
How I add semantic search to a Next.js site using Sanity Embeddings
Sanity Embeddings semantic search in Next.js is one of those features that looks complicated from the outside but is surprisingly lean to wire up once you understand the moving parts. This post covers the current native Embeddings feature built into Sanity datasets — not the older Embeddings Index API, which Sanity is sunsetting. If you found a guide that talks about a separate embeddings-index resource you have to provision via the Management API, it is stale; skip it. What Sanity Embeddings actually is Sanity's native Embeddings feature lets you mark document types for vector indexing directly inside your dataset. Sanity handles the embedding model and the vector store; you never manage a separate service. Queries use a dedicated sanity.embeddings.query GROQ function that takes a natural-language string and returns documents ranked by semantic similarity. The feature is available on Growth and Enterprise plans as of mid-2026. The workflow has three parts: Configure which document types get indexed (dataset setting or the Embeddings pane in Sanity Studio). Run a semantic query from your Next.js route handler using the Sanity client. Render the results in a search UI component. Setting up the embeddings index in your dataset Go to Manage → your project → Embeddings (or open the Embeddings pane inside Sanity Studio if your plan surfaces it there). Create an index, give it a name (e.g. site_search ), and select which document types and fields to embed. For a blog you would typically pick post with fields title , excerpt , and body (plain text extracted from Portable Text). Sanity backfills existing documents automatically. New and updated documents are re-embedded on publish via an internal webhook — you do not configure that yourself. There is no code required for the indexing step. The index name you choose here ( site_search ) is what you will pass in the GROQ query. Querying embeddings from a Next.js route handler Create a route handler that accepts a search term,
产品设计
My Next.js 16 Optimistic UI Looked Perfect. Then Someone Clicked It Five Times Fast
Everything worked. I'd wired up useOptimistic on a task list, the checkbox flipped the instant you...