AI 资讯
From Native WordPress to Headless: The Real Engineering Decisions Behind a Production Migration
Every headless WordPress conversation starts the same way — someone draws an architecture diagram with arrows pointing from a REST API to a shiny Next.js frontend, and it looks clean. Too clean. This is a post about what happens when you close the whiteboard and open the actual codebase. The Stack Decision: GraphQL vs. REST vs. Direct MySQL This is usually the first fork in the road. For this build, the client already had a well-indexed WooCommerce site. The product catalog, slugs, and taxonomy structure were already doing heavy SEO work. So the constraint was simple: nothing about the data layer changes, only how we consume it. WPGraphQL was a real option — but it meant adding a plugin dependency to a WordPress install we were actively trying to slim down. The WP REST API was already there, no installation required, and exposed exactly what we needed: products, categories, pages, and media — all queryable by slug. The decision: WP REST API, consumed server-side via Next.js fetch in Server Components. // Fetching a product by slug — preserving the existing URL structure const res = await fetch ( ` ${ process . env . WP_API_BASE } /wp/v2/product?slug= ${ params . slug } &_embed` , { next : { revalidate : 3600 } } ); const [ product ] = await res . json (); No new dependencies on the WordPress side. The legacy install runs as a lean shell — no active theme, minimal plugins, just the REST API and the data. The Site Kit Problem: Bridging Familiar Workflows This is where most migrations quietly fail the client. The previous team lived inside WordPress admin. Google Site Kit gave them traffic stats, Search Console data, and Analytics — all surfaced in a UI they knew. Ripping that away and telling them "just use Google Analytics directly" is a workflow regression, not an upgrade. The pivot here was building a lightweight admin dashboard as part of the Next.js project — not a full replacement for Site Kit, but a mirror of the metrics they actually checked daily: Page views
AI 资讯
WordPress headless Project and how to deal with
Hey everyone! Our team and I (acting as a junior backend) recently finished rebuilding GlobeVM (an enterprise Cloud, IT, and Cybersecurity provider) from a traditional monolithic WordPress site into a Headless architecture. I wanted to share our entire journey, our tech stack, the massive headaches we faced, and the solutions we engineered. If you are planning a Headless WP build soon, grab a this might save you weeks of debugging! The Tech Stack Frontend: Next.js (App Router), React, deployed on Vercel. Backend: WordPress hosted on Cloudways (Purely as a headless CMS). Data Structure: Advanced Custom Fields (ACF Pro) + Custom Post Type UI (CPT UI). SEO: Yoast SEO Premium (via REST API). Caching: Vercel Edge Cache (ISR) + Redis Object Cache on Cloudways. During the development and deployment of this website we faced several issues containing the frontend stack itself and traditional features of WordPress. I tried my best to save them all and show them all up here for everyone so that we can discuss on every section of it, maybe we could reach to even something more special :) Challenge 1: The API Was a Mess ("BFF" Architecture) When we first started, we were using the default WordPress REST API. Our Next.js frontend was making 8 different fetch() calls just to build the Blog Homepage (fetching posts, authors, categories, tags, ACF fields, etc.). We were also using messy URLs like ?_fields=id,title,acf&_embed. The Solution: We built a Backend-For-Frontend (BFF). Instead of Next.js doing the heavy lifting, we wrote a custom PHP plugin in WordPress. We created a single master endpoint (/wp-json/gvm/v1/blog-home). WordPress ran all the complex database queries, bundled the Tags, Hero Article, and Categories into one beautiful JSON array, and cached it in RAM using Transients & Redis. Only one of WordPress default api was used for our categories. Result: Next.js made one fetch call. The page loads instantly.' Challenge 2: Handling Vector Icons & ACF Our design heavily re
AI 资讯
7 Infra Improvement Strategies to Prevent Next.js Deployment Build Failures in 2026
7 Infra Improvement Strategies to Prevent Next.js Deployment Build Failures in 2026 Recently, our team's deployment pipeline started showing serious instability. Specifically, we encountered recurring build failures related to the chat build. As a result, the entire development team was preoccupied with battling these build failures. Attempts and Pitfalls Initially, I thought the --preload detection logic was the problem. I modified it to detect only specific lines, but this ended up causing issues in other areas. The recurring chat build failures were actually caused by the next.config file not properly recognizing file extensions. I modified it to allow extensions like .mjs , .js , .ts , and .cjs , but even that didn't work correctly at first, leading to some wasted effort. # .github/workflows/deploy.yml (Excerpt from initial version) - name : Run Preload Detection run : | # ... existing logic ... if [[ "$LINE" == *"some_pattern"* ]]; then echo "Preload detected" # ... fi I modified it to detect only specific lines like the above, which led to unintended behavior. // next.config.js (Initial configuration) module . exports = { // ... experimental : { // ... }, // ... }; Regarding extensions, I initially allowed only a few types, and only after experiencing chat build failures did I modify it to support more extensions. Root Causes In the end, it was a combination of several complex issues. There were flaws in the --preload detection logic, and the range of supported extensions in the next.config file was too narrow, which was the direct cause of the chat build failures. Additionally, there was confusion arising from the chat server builds being inconsistent between P1/P2 and P0 stages. Problems also occurred because the .next directory was not preserved, and the smoke gate was too lenient, failing to catch build failures. Finally, there was an unexpected side effect where the next/font/google library caused GCE outbound connection errors. Solutions To address these
AI 资讯
How to build a credit system for a Next.js AI app (Stripe + Supabase)
If you're building an AI app (image generation, transcription, an agent, anything that calls a model) you've probably realized a flat "$10/month" doesn't work. Every action costs you real money in GPU/API spend, so a single power user can torch your margins. The answer is usage credits : users buy a balance, each action spends some. Credits sound trivial. They are not. I've shipped about 10 small AI/SaaS apps, and the credit layer is where I got burned every single time. It took three patterns to fix it for good. Here they are, with copy-pasteable code for Next.js + Supabase + Stripe. Get these right and your billing won't oversell, double-charge, or strand a user's money. The three things everyone gets wrong Overdrawing. Two requests arrive at once, both read "balance = 1," both spend. Now the balance is negative and you gave away work for free. Double-granting. Stripe retries webhooks (it will ), and if you grant credits on every delivery, a $9 purchase becomes $18 of credits. Forgetting the refund. The AI job fails after you've already charged the credits. The user paid for nothing and emails you angry. Let's kill all three. Part 1. The atomic spend (overdraw becomes impossible) The mistake is doing the check in your app code: // DON'T: read-then-write has a race condition const { balance } = await getBalance ( userId ); if ( balance < cost ) throw new Error ( " insufficient " ); await setBalance ( userId , balance - cost ); // two concurrent requests both pass the check Do it in the database, in one statement, with the guard in the WHERE clause: -- balances: one row per user create table credit_balances ( user_id uuid primary key references auth . users ( id ) on delete cascade , balance integer not null default 0 check ( balance >= 0 ), updated_at timestamptz not null default now () ); -- append-only ledger = audit log + idempotency guard (see Part 2) create table credit_ledger ( id bigint generated always as identity primary key , user_id uuid not null referen
科技前沿
Steve Jobs in Exile is a fine profile of Jobs' years at NeXT
“Why don’t we just frickin’ call Apple?”
AI 资讯
How I Organize a Small Next.js Content Hub by Search Intent
When building a small content site, the framework is usually not the hardest part. The harder part is deciding what each page should be responsible for. A lot of sites start as a simple article list. That works for a while, but it becomes messy when visitors arrive with different search intents. Some users want to learn what something means. Some want download or setup information. Others are trying to fix a specific issue. Those users should not all land on the same generic page. The structure I use For a small Next.js content hub, I like to separate routes by intent: Homepage: broad entry point Learn hub: basic explanations and guides Learn detail pages: specific guide topics Download page: download or install intent Fix hub: troubleshooting entry point Fix detail pages: specific issue pages English and Japanese routes: language-specific entry points This structure is simple, but it keeps the site easier to maintain. Page role comes first Before writing a page, I define its role. A learn page answers what something is, how it works, and what a beginner should understand first. A download page answers where a user should get something, what should be checked before installing, and which platform or device matters. A fix page answers what is not working, what should be checked first, and whether the problem is related to permissions, notifications, device settings, or installation. The page role decides the title, description, internal links, and body structure. Why this helps SEO This approach helps avoid pages competing with each other. For example, a download page should not try to rank for every tutorial query. A troubleshooting page should not read like a general homepage. Each page can link to related pages, but the primary intent stays clear. That makes the site cleaner for both users and search engines. Metadata and sitemap discipline In a Next.js App Router project, I also like to keep metadata and sitemap updates close to the route change. For example: If
开发者
Qisquiz: A Quiz App for Learning Qiskit v2.X
Qisquiz: A Qiskit v2.X Certification Prep App I built Qisquiz , a web app for learning Qiskit v2.X and preparing for the IBM Certified Quantum Computation using Qiskit v2.X Developer - Associate certification exam. You can try the app here: https://qisquiz.vercel.app/ The GitHub repository is here: https://github.com/dorakingx/qisquiz The concept of Qisquiz is simple: Master Qiskit, one quiz at a time. In other words, Qisquiz is a quiz-based certification prep app that helps learners study Qiskit one question at a time. The target exam is: Exam C1000-179: Fundamentals of Quantum Computing Using Qiskit v2.X Developer Why I Built Qisquiz Qiskit is one of the most important development tools for learning and building quantum computing applications. It is useful for creating quantum circuits, running simulations, using IBM Quantum hardware, and experimenting with quantum algorithms. However, Qiskit v2.X includes several APIs and concepts that learners need to understand carefully. For example, certification prep requires knowledge of topics such as: Qiskit Runtime SamplerV2 EstimatorV2 PUBs, or Primitive Unified Blocs BackendV2 backend.target Transpilation ISA circuits Dynamic circuits OpenQASM 3 Result object handling Little-endian and big-endian interpretation These topics can be learned by reading documentation, but I felt that active practice through quizzes is especially useful for exam preparation. That is why I built Qisquiz , a quiz-based learning app focused on Qiskit v2.X. What Is Qisquiz? Qisquiz is an independent quiz-based learning app for Qiskit v2.X. The current version is organized around the 8 sections of the IBM Qiskit v2.X Developer certification exam. The current question bank includes: 120 original questions 44 code-based questions 40 hard questions 8 sections 15 questions per section Qisquiz is not an official IBM or Qiskit product. It is an independent learning tool that I built to help myself and other learners prepare more effectively. Covered E
AI 资讯
Integrating Webpay Plus into a modern stack
If you've ever worked on an e-commerce project in Chile, sooner or later you bump into Transbank. There's no avoiding it. I built a reference template that use NestJS on the backend and Next.js 16 on the frontend, and in this post I want to walk you through the whole thing: what Webpay Plus actually is, why the integration looks the way it does, and how each piece fits together. Github Repository Reference: Link A bit of context Webpay Plus is one of the most important online payment methods in Chile. The user experience is straightforward: your customer enters an amount on your site, gets redirected to Transbank's branded payment page, fills in their card details there, and comes back to your site with a result. From a UX perspective it's not as slick as Stripe Elements or a fully embedded checkout — the user always sees Transbank's domain in the address bar during the payment — but from a developer's perspective that's actually a feature. You never touch card numbers. PCI scope stays minimal. Transbank handles 3D Secure, fraud rules, and bank routing. The trade-off is that the integration model is what you might politely call classical . It's built around full-page redirects and form POSTs, not modern APIs with JSON responses and webhooks. That's important to understand up front, because it shapes every decision you'll make in the code. The integration flow, step by step Before looking at any code, it helps to have a clear mental model of what's happening . There are three distinct moments where your system talks to Transbank's system, and each one has a specific shape. First Step: When the customer clicks "Pay", the backend asks Transbank to create a transaction (amount, order ID, return URL) . Transbank returns a transaction token and a redirect URL where you must send the user. Second Step: Transbank requires the redirect to be an HTTP POST with the token in a token_ws form field, so you must generate an HTML form with a hidden token_ws input and submit it prog
AI 资讯
Next.js 16.2: 400% Faster Dev Startup, Faster Rendering, and Deeper Tooling for AI Agents
Vercel has released Next.js 16.2, featuring performance enhancements that make development startup 400% faster and rendering up to 60% quicker. The update includes AI-assisted development tools, improved Turbopack efficiency, and better error reporting. Migration from Next.js 15 is supported, and compatibility is set for Node.js 20.9 and TypeScript 5.1 or newer. By Daniel Curtis
AI 资讯
Vercel cron alternative: what to use when built-in cron isn't enough
Vercel's built-in cron triggers your serverless functions on a schedule. For simple use cases it works. But it has no failure alerts, no execution history on the Hobby plan, and no way to know whether your function actually completed successfully — only that it was called. Where Vercel cron falls short Vercel cron works by invoking one of your API routes on a schedule defined in vercel.json . The invocation is fire-and-forget — if your function times out, throws an error, or returns a non-2xx status, you get no alert. You find out when a user reports something is broken. The specific gaps developers run into: No failure alerts. Vercel does not send an email or webhook if your scheduled function fails. No execution history on Hobby. The free plan does not retain cron execution history. Timeout ceiling. Functions are subject to the same timeout limits as all serverless functions — 10 seconds on Hobby, up to 300 seconds on Pro. HTTP-only. Vercel cron calls an HTTP endpoint on your app. You cannot schedule arbitrary background work outside your deployment. No heartbeat monitoring. Even if your function is called successfully, you have no built-in way to verify it completed its work — only that it was invoked. Minimum 1-hour interval on Hobby. Sub-hourly schedules require a paid plan. If you are hitting any of these limitations, you need an external tool. Comparison at a glance Tool Schedules jobs Failure alerts Heartbeat Uptime monitoring Free tier Vercel built-in ✓ ✗ ✗ ✗ ✓ (1h min) Tickstem ✓ ✓ ✓ ✓ ✓ Upstash QStash ✓ ✓ (retries) ✗ ✗ ✓ Inngest ✓ ✓ ✗ ✗ ✓ cron-job.org ✓ ✓ (basic) ✗ ✗ ✓ Tickstem — cron + heartbeat + uptime in one API key Best for: developers who need scheduling, failure alerts, heartbeat monitoring, and uptime checks without managing multiple tools. Tickstem is an external HTTP cron scheduler with built-in monitoring. You register your Vercel endpoint as a cron job, and Tickstem calls it on your schedule — every minute if needed, regardless of your Vercel
AI 资讯
Why we built nudges before we built the dashboard (and why you should too)
Most SaaS founders build the dashboard first. It looks impressive in demos, investors love screenshots, and it feels like real progress. We did the opposite. Here's why. The real reason approvals fail When I started building TeamAutomation, I interviewed a dozen people about their approval process. Every single one said the same thing — approvals don't fail because people reject them. They fail because nobody follows up. The requester sends the request. The approver gets busy. Nobody wants to be the annoying person who keeps pinging. Days pass. Project blocked. A dashboard showing "pending approvals" doesn't fix this. The approver still has to remember to open it. Nudges are the product We ship automatic reminders at 24 hours, 3 days, and 7 days — directly in Slack where the approver already lives. No new app to open. No new habit to build. The accountability shifts from the requester to the system. That's the whole unlock. What we learned Build the thing that changes behavior first. The dashboard is just reporting. Nudges are intervention. If you're building any kind of workflow tool, ask yourself — what happens when nobody does anything? Your answer to that question is your core feature. What's next Still in early beta. Slack Directory approval pending. Zero users, full transparency. If you're dealing with approval chaos in your team, drop a comment — happy to give early access.
AI 资讯
Next.js 16 Caching for E-Commerce: Cache Components, use cache, revalidateTag, and Fresh Product Data
Caching in e-commerce is never just about speed. A fast storefront is useful only if it still shows the right price, the correct stock level, and the right experience for the current customer. That is why caching in a Next.js storefront can be deceptively hard. Some data should be shared broadly and kept warm for SEO and performance. Some data should be refreshed often. Some should never be shared between users at all. Next.js 16 gives teams a much clearer toolbox for solving this problem with Cache Components, use cache , tag-based invalidation, and explicit cache lifetime controls. Used properly, these features let you keep pages fast without drifting into stale commerce data. In this guide, I will walk through a practical way to think about caching in a modern storefront and show how to combine use cache , cacheLife , and revalidateTag for real e-commerce use cases. Why Caching Is Harder in E-Commerce Than in a Typical Content Site On a standard marketing site, most content changes infrequently. If a page is cached for a few minutes or even a few hours, the business impact is usually negligible. Commerce systems work differently. The same product page may contain: stable product descriptions and category copy semi-dynamic data such as price, availability, shipping estimates, or promotion labels private data such as cart state, recently viewed items, or customer-specific pricing Treating all of that data the same way leads to one of two bad outcomes: You cache too aggressively and serve stale prices or availability. You disable caching everywhere and lose the performance benefits that help SEO and conversion. The better approach is to split your data by volatility and audience. The Three Cache Boundaries That Matter Most For most commerce projects, the cleanest mental model is to divide data into three groups. 1. Stable catalog content This is the part of the page that usually changes only when content editors or merchandisers update the catalog. Examples: product
AI 资讯
Deploying a Next.js App to AWS with CI/CD Pipelines (Step-by-Step)
The first time I deployed a Next.js app to production, it took me three days. Not because the app was complicated — it was a straightforward portfolio site. It took three days because I had no idea what I was doing with AWS, I'd never written a GitHub Actions workflow, and every tutorial I found either skipped the hard parts or assumed I already knew them. By the time I was done, I had a deployment pipeline I was genuinely proud of: push to main, GitHub Actions runs the build, tests pass, the app deploys to an EC2 instance behind CloudFront. Zero manual steps. Zero downtime deploys. Total cost: about $5/month. This guide is the one I wish had existed. We're going to deploy a Next.js app to AWS from scratch — EC2 for compute, CloudFront for CDN, GitHub Actions for CI/CD — with every step explained so you understand what you're building, not just copying commands. Why AWS Instead of Vercel? This is a fair question. Vercel is genuinely excellent for Next.js, and for most projects it's the right call. You push, it deploys. Done. AWS makes sense when: You need to control the infrastructure (compliance, data residency, custom VPC configuration) You're running other services (databases, queues, lambdas) in AWS and want everything in the same network You want to learn infrastructure skills that transfer to enterprise environments Your app has specific performance requirements that benefit from custom CloudFront configuration You're a freelancer or consultant who wants to bill separately for infrastructure If none of those apply to you, use Vercel. This guide is for when they do. The Architecture Here's what we're building: ┌────────────────────────────────────────────────────────┐ │ GITHUB ACTIONS CI/CD │ │ │ │ Push to main → Build → Test → Deploy to EC2 │ └──────────────────────┬─────────────────────────────────┘ │ SSH deploy ▼ ┌────────────────────────────────────────────────────────┐ │ AWS EC2 INSTANCE │ │ │ │ Ubuntu 22.04 LTS │ │ Node.js 20 + PM2 (process manager) │ │ N
产品设计
After 7 Next.js 16 Caching Bugs, I Stopped Guessing and Built a System
There's a specific feeling you get after your third production caching incident. It's not panic....
AI 资讯
Cómo solucionar el error \"Text content does not match server-rendered HTML\" en Next.js
Cómo solucionar el error "Text content does not match server-rendered HTML" en Next.js Este error ocurre cuando el HTML generado en el servidor (SSR) no coincide con el árbol de React que se construye durante la hidratación inicial en el navegador. Es un problema crítico que rompe la experiencia de usuario y puede causar comportamientos impredecibles. Causa raíz En tu caso, el error está relacionado con contenido dinámico que varía entre renderizado del servidor y renderizado del cliente , probablemente por: Uso de Date() o new Date() en el renderizado (ej. fechas de eventos como JUN 9 , JUN 11 , etc.) Uso de typeof window !== 'undefined' o APIs del navegador directamente en el render Metaetiquetas o scripts que modifican el DOM antes de la hidratación (como iOS detectando fechas como enlaces) Configuración incorrecta de librerías CSS-in-JS o Edge/CDN que modifiquen el HTML Solución definitiva (pasos) ✅ Paso 1: Aisla el contenido dinámico con suppressHydrationWarning Si el contenido que varía es intencional (como fechas de eventos), envuelve solo el elemento problemático con suppressHydrationWarning={true} : // app/page.tsx o app/events/page.tsx export default function EventsPage () { const events = [ { name : ' NEXT.JS NIGHTS ' , date : new Date ( ' 2024-06-09 ' ) }, { name : ' AMS ' , date : new Date ( ' 2024-06-11 ' ) }, { name : ' LDN ' , date : new Date ( ' 2024-06-18 ' ) }, ]; return ( < div > < h2 > VIEW EVENTS </ h2 > < ul > { events . map (( event , i ) => ( < li key = { i } > < strong > { event . name } </ strong > { /* ✅ Solo este elemento usa suppressHydrationWarning */ } < time dateTime = { event . date . toISOString () } suppressHydrationWarning > { event . date . toLocaleDateString ( ' en-US ' , { month : ' short ' , day : ' numeric ' }) } </ time > </ li > )) } </ ul > </ div > ); } ⚠️ Importante : suppressHydrationWarning solo funciona en el elemento inmediato, no en hijos. Usa span , time , div , etc., no en contenedores grandes. ✅ Paso 2: Evita Da
AI 资讯
Building KindaSeen with FastAPI, Next.js, and PostgreSQL
“Did We Already Watch This?” — Building KindaSeen with FastAPI and Next.js A few months ago, my friends and I kept running into the same question whenever we talked about movies, dramas, anime, or variety shows: “Did we already watch this before?” Sometimes we remembered the title but forgot whether we had finished it. Other times, we completely forgot we had already seen it at all. That simple problem inspired me to build KindaSeen, a full-stack personal media repository designed to help users track and organize the media they’ve consumed in one centralized platform. The goal of the project was not only to create a useful application, but also to gain hands-on experience building a real-world full-stack system with modern web technologies. What KindaSeen Currently Supports User authentication with Supabase CRUD operations for personal media records TMDB-powered search functionality Watchlist system Favorites system Persistent PostgreSQL storage Dockerized backend deployment Separate frontend/backend deployment workflow Tech Stack Frontend Next.js React Tailwind CSS Shadcn/ui Vercel deployment Backend FastAPI PostgreSQL Docker Render deployment External Services Supabase Authentication TMDB API integration One of the main goals of this project was to simulate a more realistic production workflow by using a decoupled frontend/backend architecture instead of building everything inside a single monolithic application. In this article, I’ll share: Why I chose this architecture How I integrated TMDB into the application Challenges I faced during deployment What I Learned From Building KindaSeen Why I Chose This Architecture Instead of building a monolith using Next.js API routes, I decided to decouple the application into a Next.js frontend and a FastAPI backend. This decision was driven by three main factors: AI Compatibility & Future Proofing : While researching the job market, I noticed that most companies building AI products heavily rely on Python. By choosing FastA
AI 资讯
I Spent 2 Months Building a 150+ Tool Website with $0 Server Cost
📚 This is Part 1 (Opening) of the UtlKit Tech Series — Next: [Architecture & Trade-offs →] As a frontend developer, I've used countless online tools. And almost all of them suck: Sign-up required — just to format a JSON string? Ad overload — the actual tool gets squeezed into a corner Privacy concerns — your JSON might contain API keys, and the tool sends it to a server Fragmented — formatters on one site, Base64 on another, hashing on a third So I decided to build one that doesn't: no sign-up, no ads, pure client-side computation, data never leaves the browser. The goal was simple — if I need this tool, someone else does too. The result is utlkit.com : 150+ tools, 8 categories, zero server costs. Requirements Requirement Meaning Pure client-side All logic runs in the browser Zero server cost Static hosting, no Node.js backend 150+ pages One page per tool, SEO-friendly Bilingual (EN/ZH) i18n support Dark/Light mode User preference Mobile responsive Works on all devices Why Not Other Frameworks? Option Pros Cons Verdict Vanilla HTML/JS Simple Managing 150+ pages is painful Too slow VuePress / VitePress Fast Docs-oriented, not for interactive tools Not flexible enough Nuxt SSR Powerful Needs a server Violates zero-cost principle Next.js 15 + output: 'export' SSR SEO + client interactivity + static hosting Has pitfalls (covered later) ✅ Best balance The Key Decision: output: 'export' // next.config.js const nextConfig = { output : ' export ' , // Static export trailingSlash : true , // Required for static files images : { unoptimized : true }, // No image optimization server } This means: ✅ Build output is plain HTML/CSS/JS files ✅ Deployable to any static host (Cloudflare Pages, Vercel, GitHub Pages) ✅ Zero server cost ❌ No API Routes, no Server Components, limited dynamic routing Deployment: Zero Cost on Cloudflare Pages Build output : out/ directory, ~14 MB Hosting : Cloudflare Pages Domain : utlkit.com Monthly cost : $0 Build Pipeline npm run build → next build ( o
AI 资讯
I built an AI conversation simulator because I kept chickening out of real talks
Last year I needed to ask for a raise. I knew my number, I'd read the guides, I had bullet points in my notes app. Then my manager said "let's chat about your goals for next quarter" and I said "sounds great, looking forward to it" and hung up. Never brought up money. Same thing kept happening elsewhere. Coworker taking credit for my work, I said nothing. Relationship that should've ended months earlier, I kept postponing. I always knew what to say. I just couldn't say it with someone actually looking at me. So I started building a thing to practice on. That thing became cosskill . What it actually is You pick a persona, tell it the situation in a sentence, and start talking. The persona doesn't help you. It holds position and pushes back. You practice not folding. Think of it as a flight simulator for hard conversations. You rehearse until your opener comes out steady, then go do the real thing. 20 personas across five categories: Operators (Musk, Jobs): first-principles thinking, harsh product feedback Strategists (Trump, Buffett): treat everything as a deal or a bet Relationship (Ex, Coworker): breakups, workplace friction, family money Philosophy (Socrates, Aurelius, Confucius, Sun Tzu, four more): each tradition frames problems differently Psychology (Rogers, Rosenberg, Ellis, Frankl, Kahneman, Jung): therapeutic frameworks on real situations These aren't celebrity impressions. The Buffett persona won't hype your startup idea. It'll ask "what's the downside?" and keep asking until you have something concrete. Tech stack Next.js 16 on Cloudflare Workers. DeepSeek for inference. Cloudflare D1 (SQLite at edge) for the bits that need to persist. No user accounts, chat history lives in localStorage. Monthly cost stays low enough that the free tier (10 messages/day) doesn't worry me. Why I made these choices DeepSeek instead of GPT-4/Claude. Each conversation is 10-30 messages. At GPT-4 pricing a free product bleeds money. DeepSeek gives maybe 90% of the quality for
AI 资讯
I built PhysioFlow — clinic software for Indian physiotherapists, solo in a week
A physiotherapist asked me a simple question a couple of months ago: "Can you build something to run my whole clinic?" So I did — solo, in about a week. Here's the full 2.5-minute walkthrough 👇 What PhysioFlow does PhysioFlow runs an entire physiotherapy clinic from one screen — built for India (₹, GST, WhatsApp, +91): Dashboard — attendance, collections & pending bookings at a glance Patient files — recharge session packs, track usage, auto-generate GST-ready bills Attendance in seconds with a QR scan Online bookings that convert straight into a patient file Reports — daily ledger, revenue, CSV/PDF export Patient portal — patients see their own sessions & prescriptions The stack Next.js + Supabase + TypeScript — multi-tenant, with row-level security so no clinic's data ever leaks to another. Try it Live now with a 14-day free trial, no card needed → https://physioflow.devfrend.com I'm Amar, a full-stack & AI engineer. I design and build products like this end-to-end. I'm open to work — SaaS builds, MCP servers, LLM apps & automation. Reach me on LinkedIn .
AI 资讯
Why my single Next.js app runs 4 different domains (and how the proxy.ts decides who sees what)
> TL;DR — I run four different domains off one Next.js codebase: a marketing site at pagestrike.com , an authenticated app at app.pagestrike.com, a public publishing domain at pagestrike.app, and customer-owned domains. The trick isn't deploying four apps — it's a single proxy.ts that reads the host and rewrites/redirects/passes-through per-request. This post walks through why I chose this shape, the parts I got wrong, and the cookie-domain trick that makes it all stick. Stack: Next.js 16 App Router , Supabase , Vercel , one proxy.ts file (~370 lines). This is the second post in my build-in-public series on PageStrike . Last week I wrote about the 6-CTA architecture — modeling conversion intent as a discriminated union so one launch could be a checkout, a COD form, or a calendar booking. This post is about a different primitive: modeling host as routing context so one codebase can serve four very different audiences. Why four domains, not one Most SaaS apps live at one domain — say myapp.com with /dashboard under it. That works until you grow into edge cases that don't fit: Marketing pages get spammed by your own dashboard headers. Your marketing nav says "Sign in / Pricing / Blog". Your dashboard nav says "Launches / Contacts / Settings". You either A/B them with conditional logic everywhere or you live with the noise. Public user-generated pages share your domain reputation. When a customer publishes a landing page at myapp.com/p/[slug] , every spammy LP from a free-tier user drags down myapp.com 's sender reputation, search trust, and ad-account standing. Google and Meta penalize the host, not the path. Custom domains don't route cleanly. A customer who buys acmewidgets.com and points it at your app expects their LP at acmewidgets.com/ — not myapp.com/p/acme-widgets . You need a rewrite that's transparent to the visitor, doesn't 404 on _next/static/* , and survives RSC prefetches. I split PageStrike — a free AI landing page builder — across four hosts to solve al