Cómo construí un clon de Linktree en 6h con Claude Code (2/2)
Race conditions, WebViews de Instagram y 8.000 líneas en un commit: el making of técnico de Taglify
¡Hola Viber! 👋
Esta newsletter tenía que salir mañana, pero mañana también tenemos el encuentro virtual con los PRO de la newsletter y quiero que todo el mundo tenga tiempo de leerla, así que hoy, como te prometí, te traigo el paso a paso técnico de cómo construí taglify.cc con Claude Code.
Pero antes, un poco de contexto rápido para los que se incorporan tarde:
Taglify es una alternativa a Linktree con dominio propio, pestañas (tabs) ilimitadas, QR (individual) por enlace, modo oscuro y perfiles que Google puede indexar de verdad. Ya lo había construido antes con Lovable.
Esta vez, lo rehice desde cero y en 5 días estaba online.
Vamos al lío.
Por qué tiré la versión anterior a la basura
La primera versión de Taglify la hice con Lovable. Funcionaba. Tenía fondos de tarjeta con imágenes de Pexels, diseños bonitos, intentando emular un poco la estética de Linktree. Quedaba bien.
Pero había dos problemas de fondo:
1. El SEO era inexistente. Lovable genera apps con React + Vite, que es client-side rendering puro. Cuando Google llega a un perfil como taglify.cc/polmarza, recibe un HTML vacío: un <div id="root"></div> y poco más. Todo el contenido lo inyecta JavaScript después, pero los robots ya se han ido. Para una app interna, eso no importa. Para un producto donde el valor está en que tu perfil aparezca en Google y se vea bien cuando lo compartes en LinkedIn... es un problema gordo.
2. Me había complicado demasiado. Fondos con imágenes, múltiples layouts, demasiadas decisiones de diseño para el usuario. Quería algo ágil, funcional, práctico. No un editor de diseño gráfico.
Así que decidí empezar de cero con Claude Code y el stack que yo eligiera: Next.js con SSR, donde cada perfil es una URL con HTML completo desde el servidor. Google lo indexa sin problema. Cada usuario tiene su propio Open Graph dinámico cuando comparte su enlace en redes. Y el usuario no tiene que decidir entre 47 fondos distintos.
Día 1: del cero al MVP (21 de febrero)
https://www.taglify.cc/polmarza
El primer día fue una maratón. En una sola sesión pasé de cero a tener:
Scaffold completo del proyecto (inicialmente con monorepo Turborepo + Next.js + Astro para la landing)
Dashboard con preview en tiempo real (panel izquierdo para editar, derecha para ver el resultado al instante)
Landing page funcional
Login con Google OAuth
Perfil público con QR y modo claro/oscuro
Onboarding en 3 pasos (username -> info del perfil -> preview)
SEO completo con metadatos dinámicos, Open Graph y sitemap
9 commits ese día. El proyecto ya era usable.
Dato curioso: empecé con la landing en Astro (un framework de generación estática) y la app en Next.js, separadas en un monorepo. A las pocas horas me di cuenta de que no tenía sentido mantener dos apps y un monorepo entero para un solo producto. Migré la landing directamente dentro de Next.js y limpié todo el tooling sobrante. Turborepo, el paquete de ESLint compartido, la config de TypeScript... todo fuera.
Lección: empieza simple. Si necesitas escalar la infraestructura, ya lo harás cuando lo necesites, no antes.
Día 2: la pesadilla del OAuth en móvil
Aquí es donde empezó lo divertido. Todo funcionaba perfecto en desktop. Abres Chrome, haces login con Google, entras al dashboard. Limpio.
Pero en móvil... caos.
El problema: cuando alguien abre tu enlace de Taglify desde Instagram, TikTok, LinkedIn o Twitter, esas apps no abren Safari o Chrome. Abren un navegador interno (un WebView). Y Google tiene una política muy clara: bloquea OAuth en WebViews. Devuelve un error disallowed_useragent y el usuario se queda mirando una pantalla de error sin entender nada.
La solución fue detectar si el usuario está en un WebView (comprobando el User-Agent para identificar Instagram, Facebook, LinkedIn, TikTok, X...) y, en ese caso, en lugar de intentar hacer el OAuth dentro de ese navegador restringido, forzar la apertura en el navegador del sistema. Parece simple, pero tiene sus matices según la plataforma.
Esto me costó 6 commits repartidos entre el día 1 y el 2. Seis. Solo para que “Iniciar sesión con Google” funcionara bien en todos los contextos. Es el tipo de cosa que no ves hasta que tienes usuarios reales intentando entrar desde la app de Instagram.
Día 3: la race condition que te arruina el sábado
Este fue el bug más sutil y el que más me enseñó.
Después de hacer login con Google, Supabase te redirige a un callback (/auth/callback) que establece la sesión del usuario. Ese callback hacía un redirect(302) al dashboard. Lógico, ¿no?
El problema: el navegador recibía la redirección y navegaba al dashboard antes de haber almacenado las cookies de sesión que venían en la respuesta. Resultado: el dashboard se renderizaba sin contexto de autenticación. El usuario había hecho login correctamente, pero la página pensaba que no estaba autenticado.
Un bug de race condition entre la navegación y el almacenamiento de cookies. De esos que funcionan “a veces” y te hacen dudar de tu propia cordura.
La solución fue cambiar el enfoque: en lugar de devolver un 302 redirect, el callback ahora devuelve una página HTML con status 200. Esa página tiene las cookies ya establecidas en la respuesta. Luego, un pequeño script de JavaScript hace la redirección. Para cuando el script ejecuta, las cookies ya están guardadas.
Pasé de un redirect “instantáneo” del servidor a un redirect “controlado” del cliente. Tres líneas de código. Tres commits para encontrar el problema.
Día 3 (tarde): organizaciones en una sola sesión
Con la autenticación estable, me puse con la feature más grande del proyecto: el sistema de organizaciones.
En un solo commit (el más grande del proyecto, con casi 8.000 líneas de código), implementé:
Registro de organizaciones con email (sin Google OAuth, contraseña manual)
Onboarding de organización en 3 pasos
Branding corporativo que se propaga a todos los miembros
Importación masiva de miembros por CSV/XLSX
Panel de administración con gestión de miembros
13 rutas de API nuevas
¿Por qué todo en un commit? Porque era una feature que dependía de sí misma en todas sus partes. No podías tener el panel de admin sin las rutas de API, ni las rutas sin el modelo de datos, ni el modelo sin el onboarding. Era todo o nada.
Si quieres que tu equipo use taglify, hablemos.
Esta feature necesita ser pulida a parte 🤓
Días 4-5: pulir, localizar, lanzar
Los últimos dos días fueron de refinamiento:
Todo al español. Botones, labels, placeholders, mensajes de error. Todo. Taglify es un producto para el mercado hispanohablante primero.
Nuevo logo. Del emoji sonriente al cuadrado rojo con la “T” que ves ahora.
Landing renovada. Los casos de uso reales (el eco-consciente, el del congreso de mañana, la que no pierde un lead) y las 6 features con el QR por enlace destacado como diferenciador.
Descarga de QR. Que el usuario pueda bajarse el QR de su perfil en negro o blanco para imprimirlo.
Qué aprendí (en resumen)
1. Empieza simple, de verdad. Monorepo con Turborepo para un solo producto fue overkill. Lo quité al día siguiente.
2. El 80% de los bugs de autenticación son de móvil. En desktop todo funciona siempre. Los WebViews, los PWAs, las in-app browsers... ahí es donde viven los dragones.
3. Un redirect 302 no es tan inocente como parece. Las race conditions entre navegación y cookies son reales. Si tu flujo de auth tiene redirects encadenados, prueba devolver HTML con JS redirect.
4. El QR por enlace individual es un diferenciador real. Linktree solo tiene QR del perfil general. Que cada link tenga su propio QR significa que puedes mostrarle a alguien exactamente lo que necesita, no tu perfil entero.
5. Claude Code no es mágico, pero te devuelve el control. Con Lovable, no eliges el stack. Con Claude Code, tú decides Next.js, SSR, Supabase, la estructura de la base de datos... y eso, cuando el producto lo requiere, marca toda la diferencia.
Los números
32 commits en 5 días
De cero a producción con auth, organizaciones, QR y SEO
6 commits solo para arreglar OAuth en móvil
1 commit de 8.000 líneas para el sistema de organizaciones
3 iteraciones de landing (Astro → Next.js → rediseño con personas)
Si quieres probar la aplicación: taglify.cc
Y si eres usuario PRO, nos vemos mañana y te cuento los detalles que no caben aquí 😜
Pol Marzà
PD: Si te ha gustado la newsletter y/o te gusta el contenido que comparto, me ayudaría mucho que compartieras esta publicación con otras personas 💚




