Case study · 3 min read
Dev Link
All your developer links on one shareable page.

- My role
- Built end to end from the challenge design: front end, Firebase data layer and deployment.
- Timeline
- Jul 2024 - Feb 2025
- Stack
- Next.js 14, TypeScript, Tailwind CSS, Firebase Auth, Firestore, Cloudinary, Framer Motion, React Query
Dev Link lets you sign up, add your links (GitHub, YouTube, LinkedIn and more), watch them appear in a live phone preview and share a public profile URL. It started from a Frontend Mentor challenge and became a small full-stack app on Firebase.
- 5screens: login, sign-up, link editor, profile and public preview
- 0servers to run: Firebase handles auth and data
- 12commits
The problem
Developers keep their links scattered: a GitHub here, a portfolio there, a talk on YouTube. One page that holds them all is a small idea, and it is a good size for learning how accounts, data and public pages fit together.
I used the project to practise Firebase Auth and Firestore, protected routes in the App Router, and building a pixel-faithful UI from a design brief.
Constraints
- A fixed design. The Frontend Mentor brief decides layout and states.
- No backend server. Firebase had to cover authentication and storage.
- Solo, small scope, so the interesting choices are about structure rather than scale.
Approach
A Next.js App Router project with pages for login, sign-up, the link editor, profile details and a public preview. Firebase Auth handles accounts. Links live in a Firestore collection with the platform name, the URL, the owner and a colour. A configuration table maps each platform to its icon and style, and profile pictures go to Cloudinary. An auth context holds the signed-in user for the whole app.
No custom server: the browser talks to Firebase and Cloudinary directly.
In the app
Key decisions
01Protected routes that remember where you were
- Context
- Sending everyone to the same page after login is a small annoyance that adds up.
- What I chose
- A route guard watches Firebase's auth state. If you are signed out it saves the page you wanted in session storage and sends you to login; after login it returns you there, or to your link editor if there was nothing saved.
- What I passed on
- Always redirect to the dashboard.
- Trade-off
- A little state in session storage.
02A live preview that mirrors the form
- Context
- People want to see what their page will look like while they edit it.
- What I chose
- A phone-shaped preview reads the same state as the form, so every change shows instantly, with each platform in its own colour and icon. It reflects the editor's state; it is not a live Firestore subscription.
- What I passed on
- Save first, then show a separate preview page.
- Trade-off
- The preview can show something that is not saved yet, so saving stays an explicit step.
03A public page with a shareable URL
- Context
- The whole point is that other people can open it.
- What I chose
- The preview page is public under a per-user URL with a copy-to-clipboard button, and link validation covers custom platforms so pasted URLs have to look right.
- What I passed on
- Keep profiles private and export an image.
- Trade-off
- Profiles are public by design, which is the feature and also the thing to be careful with.
Challenges
- Matching the brief across breakpoints and states took most of the front-end time.
- Validating URLs per platform. A GitHub link and a custom link are not the same shape, and a later commit tightened the rule for custom platforms.
- Learning Firestore's model. My first public-page query fetches every user's links and filters in the client, which works for a demo and is a privacy and performance problem for a real product.
Results
Dev Link is deployed and works end to end: accounts, a link editor with a live preview, and a public page you can share. There are no usage numbers to report.
It taught me the shape of a Firebase app and showed me exactly what I would do differently, which is the list below.
What I would do next
- Query links by owner on the server side instead of fetching everyone's and filtering in the browser.
- Write Firestore security rules so reads and writes are scoped to the right user.
- Add drag-and-drop reordering, which the original design calls for and I have not built.
- Add tests; there are none.