Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
YouTube Security VideosNutanix advances legacy and AI app management with AMD(01.10.2026 um 16:00 Uhr)
•
YouTube Security VideosPC-WELT: 32 TB SSD-Speicher in der HMX 6!(01.10.2026 um 16:15 Uhr)
••••
Videos & KonferenzenPC-WELT: 32 TB SSD-Speicher in der HMX 6!(01.10.2026 um 16:15 Uhr)
••
Sicherheitslücken (CVE)USN-8857-1: KCoreAddons vulnerability(01.10.2026 um 12:48 Uhr)
•••
YouTube Security VideosNutanix advances legacy and AI app management with AMD(01.10.2026 um 16:00 Uhr)
•
YouTube Security VideosPC-WELT: 32 TB SSD-Speicher in der HMX 6!(01.10.2026 um 16:15 Uhr)
••••
Videos & KonferenzenPC-WELT: 32 TB SSD-Speicher in der HMX 6!(01.10.2026 um 16:15 Uhr)
••
Sicherheitslücken (CVE)USN-8857-1: KCoreAddons vulnerability(01.10.2026 um 12:48 Uhr)
•••
Intelligence View
⚡ tsecurity.de Intelligence

How I built a context-switching profile builder with Next.js, dnd-kit, and Supabase

I've been building Introlo, a link-in-bio tool where your single URL shows different content depending on the context you set. I call these "persona modes" — y…

Beitrag
0
Seite
0
↗ Quelle (dev.to)
Social ReaktionenReagiere als Erste:r — dein Feedback zählt!

I've been building Introlo, a link-in-bio tool where your single URL shows different content depending on the context you set. I call these "persona modes" — you might show one version of your profile when you're networking, another when you're fundraising, another when you're promoting creative work.



This post is about how I built the Studio (the profile editor) and the architectural decisions behind making persona modes work. Hopefully useful if you're building anything with dynamic content rendering, drag-and-drop interfaces, or multi-state profiles.






The Stack




  • React 18 + Next.js 14 (App Router)

  • TypeScript

  • Tailwind CSS (custom component layer, no shadcn/MUI/Chakra)

  • Supabase (auth + database)

  • Stripe (payments)

  • dnd-kit (drag-and-drop)



No component library. Every UI element is custom. That was a deliberate choice I'll get into below.






The Core Problem: One URL, Multiple States



The fundamental challenge is this: a single URL (introlo.com/yourname) needs to render different content based on which persona mode the owner has active. The visitor doesn't choose. The owner sets it in Studio.



This means the rendering layer needs to:




  1. Resolve the username from the URL

  2. Look up which persona mode is currently active

  3. Fetch the blocks, layout, and content associated with that mode

  4. Render it — fast



The important architectural decision: persona modes aren't separate pages or profiles. They're visibility layers on top of a single set of content blocks. Each block has a visibility array that defines which modes it appears in. When you switch modes, you're not loading a different page. You're filtering which blocks render.



This matters for performance. There's no additional database query when the mode changes. The blocks are already loaded. The mode switch is a client-side filter operation.






Why dnd-kit Over Alternatives



I evaluated three options for drag-and-drop: react-beautiful-dnd, dnd-kit, and building from scratch with native drag events.



react-beautiful-dnd was the obvious first choice since it's well-documented and widely used. But it's been in maintenance mode and the API felt rigid for what I needed. I wanted drag handles, sortable lists, and the ability to drag blocks between different containers (moving a block from one section to another).



Native drag events would have been lightweight but the amount of edge-case handling (touch devices, scroll containers, accessibility) would have eaten weeks.



dnd-kit won because:




  • It's modular. You import only what you need (@dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities).

  • The sensor system handles mouse, touch, and keyboard out of the box.

  • Custom drag overlays let me show a styled preview of the block being dragged, not just a ghost clone.

  • It plays well with React 18's concurrent features.



The one thing that tripped me up early: dnd-kit's sortable context needs a stable array of IDs. If your block list is filtered by persona mode, the ID array changes when you switch modes. I had to make sure the sortable container re-initializes cleanly on mode switch rather than trying to reconcile the old sort order with a new filtered list.






No Component Library - Why and How



This was the most opinionated decision in the stack. Every tutorial and boilerplate I looked at used shadcn/ui or Radix or Chakra. I skipped all of them.



The reason: Introlo's design language is specific. Dark warm backgrounds (#1C1208), cream text (#FAF6EF), orange accents (#F97316), Instrument Serif for headings, DM Sans for body. Geometric unicode icons instead of emoji. No rounded-everything Material Design aesthetic.



If I had started with a component library, I would have spent more time overriding defaults than building. Every Button component would need custom variants. Every Dialog would need restyling. The "saved time" from a library disappears fast when your design system doesn't match its assumptions.



Instead, I built a thin component layer on top of Tailwind:




  • A Block component that handles the shared structure (drag handle, visibility toggle, mode badge, expand/collapse)

  • A Panel component for the right-side editing interface

  • A ModeSelector that manages the active mode state and broadcasts it to the block list



Total custom components: maybe 15-20. Each one does exactly what I need and nothing else. They're small enough that I can read any component file in under 30 seconds.



The tradeoff is real: no pre-built modals, no pre-built dropdowns, no pre-built tooltips. I built those by hand. But each one matches the design system perfectly without fighting overrides.






Supabase as the Data Layer



Supabase handles two things: auth and the profile data store.



Auth was straightforward with @supabase/ssr. The Next.js App Router integration works well once you understand the middleware pattern for session refresh.



The data model concept is simple: profiles own blocks, and each block knows which persona modes it should appear in. When the public profile renders, it checks which mode is active and filters the blocks accordingly. The filtering happens at the query level so you're not loading unnecessary data.



Supabase's Row Level Security handles the read/write boundaries so the public profile page and the authenticated Studio editor can share the same tables without exposing anything they shouldn't.



One thing I'd do differently: I'd use Supabase Realtime from the start for the Studio preview. Right now, the preview updates on save. With Realtime, the preview could update as you type, which would make the editing experience feel much more responsive.






Stripe Integration: Subscriptions + One-Time Payments



Introlo has three tiers: Free, Pro ($12.99/mo), and Lifetime Pro ($59 one-time). Stripe handles both the recurring subscription and the one-time payment.



The challenge was managing two different payment types in a single billing system. Subscriptions use Stripe's subscription API. Lifetime Pro uses a one-time payment intent. But in the app, both need to resolve to the same question: does this user have Pro access or not?



The solution: a unified access check that doesn't care how you got Pro. Stripe webhooks listen for the relevant subscription and payment events, then update the user's access level accordingly. Whether you're paying monthly or bought lifetime, the app treats you the same.



This keeps the codebase simple. Feature gates check one thing. Stripe handles the complexity of different payment flows behind the scenes.






What I'd Do Differently



Start with Supabase Realtime for the editor. The save-then-preview loop adds friction. Live preview would make Studio feel like a proper design tool.



Invest in keyboard shortcuts earlier. Power users (and I'm one of them) want to reorder blocks, switch modes, and toggle visibility without touching the mouse. I'm adding these now but they should have been in from the start.



Build the mobile editing experience sooner. Most of my users check their profile on mobile. Some want to make quick edits on mobile. The Studio is desktop-first right now and that's a gap.






Try It



If any of this was interesting, you can try Introlo at introlo.com. It's free to start. Bootstrapped and actively looking for feedback — especially from devs who have opinions about how profile builders should work.



If you're building something similar with dnd-kit or Supabase, happy to answer questions in the comments.

🔍 CTI & Forensik

Cyber Threat Intelligence & Forensik

Bedrohungsgraph · ATT&CK-Mapping · Exploit-Belege
CTI Threat Relationship Graph
Akteure · Techniken · Beziehungen
2 Knoten · 1 Relationen
CVE / Incident Threat Actor Software MITRE ATT&CK CWE Weakness IoC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten How I built a context-switching profile builder with Next.js, dnd-kit, and Supabase

Thematisch verwandte Begriffe: built, contextswitching, profile, builder · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

💬 Kommentare werden geladen…
Zum Aktualisieren ziehen
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag