DEV Community

Voke
Voke

Posted on

Building in Public: CV Analyzer -Act 3 · Scene 2 : Fixing and Rendering the AuthPage

This post shows how to add an authentication page to a React app using React Router, correctly wiring routes and preparing the UI layer for user-based access and future scaling.

Click here for Act 3 · Scene 1

Table of Contents

Act 3 · Scene 2 : Fixing and Rendering the AuthPage

In this scene, I introduce authentication into a React MERN application by wiring an AuthPage into the routing system and laying the groundwork for user based access control.

Overview

With navigation and routing in place, the next logical step was to introduce authentication.

At first, I debated skipping it entirely. But the more I stared at the app, the more obvious it became that authentication would eventually be required not just to identify users, but to control what they are allowed to do.
So instead of pretending auth doesn’t exist, I decided to face it early.

This scene focuses on:

  • Introducing an AuthPage
  • Rendering it properly through the router
  • Introducing a reusable Button component for shared UI behavior

The goal wasn’t to build auth fully yet, but to prepare the application for it.

Why Authentication Shows Up Now?

Authentication influences architecture decisions early on:

  • What users can see
  • What they can do
  • What eventually needs protecting

If I delay it too long, it will sneak up on me later without sneakers and will force some ugly refactors. So it's best to face it head on now

Architectural Foreshadowing (Thinking Ahead)

Introducing authentication automatically implies a few future decisions.

First: data persistence.

Once users can sign up or log in, I will need a database to store user records securely. And fetch them when needed. I am not introducing the database yet, but it’s already part of the mental model for where this product is headed. We will talk more about it when we cross that bridge.

Second: backend control and scaling

Authentication almost always means a backend, unless I hand over everything to a managed service like Firebase. But for this project, I want more control over how authentication is handled, especially with scaling in mind.

Vertical scaling, in particular, will require being intentional about how auth logic is structured. More on that later. This is already looking mouth watering. I am salivating already. MAAAAAN! I am in love with this whole process.

So, for now, let’s get started with authentication, and what better place to start than the AuthForm? And just to quickly add, I will not be implementing Google authentication in here yet, at least for now.

Creating the AuthForm and AuthPage

I started by creating an AuthForm component inside a dedicated auth folder under components alongside its SCSS module.

Folder structure:

components/
  auth/
    AuthForm.tsx
    AuthForm.module.scss
Enter fullscreen mode Exit fullscreen mode

Then I created an AuthPage inside the pages directory to act as the route-level wrapper. The AuthPage inside the pages directory is to host the AuthForm.

Code below:

import AuthForm from "../components/auth/AuthForm";

const AuthPage = () => {
  return <AuthForm />;
};

export default AuthPage;
Enter fullscreen mode Exit fullscreen mode

This keeps routing concerns separate from UI logic. As Pages handle routing, while Components handle UI.

Making the Route Exist

Of course, nothing renders until the router knows about it.

And I hope you remember this image from the previous scene:

So back to App.tsx.
I added the /auth route to the route tree:

children: [
  { path: "/", element: <HomePage /> },
  { path: "/auth", element: <AuthPage /> },
];
Enter fullscreen mode Exit fullscreen mode

With this change, the /auth route now renders correctly.

While I Was At It With Auth… A Button Component Was Born

While building the AuthForm, I noticed that I would be making use of a styled Button more than once.

So instead of hardcoding styles, I introduced a reusable Button component inside the shared ui folder:

interface ButtonProps {
  children: React.ReactNode;
  className?: string;
  onClick?: () => void;
  type: "submit" | "button";
}

const Button = (props: ButtonProps) => {
  return (
    <button
      className={`${classes.button} ${props.className || ""}`}
      onClick={props.onClick}
    >
      {props.children}
    </button>
  );
};
Enter fullscreen mode Exit fullscreen mode

Later, I will move the ButtonProps out of this Button.tsx file. I will store it in another file, which I will call interfaces.

Mental Model

Right now:

  • Routes unlock pages, well Auth page for now
  • Pages host components
  • UI building blocks reduce duplication
  • Authentication exists as infrastructure, not a feature sprint

Why This Scene Matters

This scene shows that I:

  • Think about users and permissions early
  • Build reusable UI intentionally
  • Prefer steady foundations over rushed features

Thanks for reading.
Let’s move on to the Next Act.

We in the Building…
Building in Progress…

Top comments (0)