S

SideButton Marketing Website Knowledge Module

Portal Login — SideButton Marketing Website Knowledge Module

Login page for the SideButton Publisher Portal. Server-side rendered (SSR) page using the Astro Layout with Header and Footer. Features a centered email-only login form (no password field). On succes…

Available free v1.0.3 Browser
$ sidebutton install sidebutton.com
Download ZIP
/login 95% confidence Verified 2026-02-21

What This Is

Login page for the SideButton Publisher Portal. Server-side rendered (SSR) page using the Astro Layout with Header and Footer. Features a centered email-only login form (no password field). On success, redirects to /portal or a server-specified redirect URL. If the user is already authenticated (Astro.locals.auth), the server redirects to /portal before rendering the page. Displays demo account emails in a hint section below the form.

URL Patterns

PatternDescription
/loginPortal login page
/login (authenticated)Server-side redirect to /portal (page never renders)

Page Structure

+--[Header: sticky banner]---------------------------+
|                                                     |
|  [main#main-content — min-h-[80vh], centered]       |
|    [.w-full.max-w-sm]                               |
|                                                     |
|      [.text-center.mb-8]                            |
|        [Logo link → /] SideButton "S" SVG           |
|        H1: "Sign in to Publisher Portal"            |
|        P: "Enter your email to access your          |
|            dashboard"                               |
|                                                     |
|      [form#login-form.space-y-4]                    |
|        Label "Email address" + input#email          |
|        [#error-message] hidden by default           |
|        Button#submit-btn "Sign in"                  |
|                                                     |
|      [.mt-8.pt-6.border-t]                          |
|        Demo accounts hint (3 emails)                |
|                                                     |
+--[Footer: 6-column grid]---------------------------+

Key Elements

ElementSelectorNotes
Main content areamain#main-contentmin-h-[80vh], flex centered, px-4
Form container.w-full.max-w-smMax width 24rem (384px)
Logo linkmain a[href="/"]SVG "S" logo in green #15C39A, links to homepage
Page headingh1"Sign in to Publisher Portal", text-2xl font-bold
Subheadingh1 + p"Enter your email to access your dashboard", text-text-secondary
Login formform#login-formspace-y-4 layout, standard <form> with submit handler
Email labellabel[for="email"]"Email address", text-sm font-medium
Email inputinput#emailtype="email", name="email", required, placeholder "[email protected]", autocomplete="email"
Error message#error-messagehidden class by default; red text on red-50 background
Submit buttonbutton#submit-btn"Sign in", type="submit", bg-primary green, full width
Demo hint.mt-8.pt-6.border-t pLists 3 demo emails: [email protected], [email protected], [email protected]

Data Model

FieldTypeDescription
emailstring (email)Publisher email address, trimmed before submission

API Request (POST /api/auth/login)

FieldTypeDescription
emailstringFrom #email input, trimmed

API Response (success)

FieldTypeDescription
redirectstring (optional)URL to redirect to (default: /portal)

API Response (failure)

FieldTypeDescription
errorstringError message (e.g., "Login failed")

States & Variations

StateTriggerVisual Indicator
DefaultPage loadEmpty email field with placeholder "[email protected]", "Sign in" button
Input focusedClick/tab into emailRing-2 green outline (ring-primary/50), border changes to primary color
SubmittingForm submitButton disabled, text changes to "Signing in..."
Validation error (browser)Submit with empty emailBrowser-native required validation popup (no custom JS)
Server errorAPI returns non-ok#error-message unhidden, shows red error text on pink background
Network errorFetch throws#error-message shows "Network error. Please try again."
SuccessAPI returns okwindow.location.href set to data.redirect or /portal
Already authenticatedServer detects Astro.locals.authImmediate 302 redirect to /portal (page never renders)

Responsive Behavior

BreakpointBehavior
All widthsForm is max-w-sm (384px), centered with px-4 padding
Mobile (<640px)Full-width form within padding, stacked layout
Desktop (>640px)Form centered in min-h-[80vh] area with Header above and Footer below

Key Differences from /connect

Aspect/login/connect
PurposePublisher Portal accessChrome extension auth
LayoutFull site chrome (Header + Footer)Standalone card, no chrome
FieldsEmail only (no password)Email + password
API endpoint/api/auth/login/api/mcp/login
On successRedirect to /portalShow success view, auto-close
RenderingSSR (requires Astro server runtime)Static HTML
Form element<form> with submit event<div> with click handler
StylingTailwind CSS utility classesInline <style> block

Common Tasks

1. Verify login form renders

  1. Navigate to /login
  2. Confirm Header is visible at top
  3. Confirm h1 reads "Sign in to Publisher Portal"
  4. Confirm subtitle reads "Enter your email to access your dashboard"
  5. Confirm input#email exists with placeholder "[email protected]"
  6. Confirm button#submit-btn reads "Sign in"
  7. Confirm Footer is visible at bottom

2. Login with valid credentials

  1. Click input#email
  2. Type [email protected]
  3. Click button#submit-btn (or press Enter)
  4. Verify button text changes to "Signing in..."
  5. Verify redirect to /portal page

3. Verify browser-native validation

  1. Leave email empty
  2. Click button#submit-btn
  3. Verify browser shows native "Please fill out this field" tooltip (from required attribute)
  4. Type notanemail (no @ symbol)
  5. Click button#submit-btn
  6. Verify browser shows native email format validation message

4. Verify server error handling

  1. Type an unregistered email (e.g., [email protected])
  2. Click button#submit-btn
  3. Verify #error-message becomes visible with error text
  4. Verify button re-enables with text "Sign in"

5. Verify demo accounts hint

  1. Scroll below the form
  2. Verify hint text lists 3 emails: [email protected], [email protected], [email protected]
  3. Verify hint is separated by a top border

6. Verify logo link

  1. Click the SideButton "S" logo above the heading
  2. Verify navigation to / (homepage)

Tips

  • This page is SSR-only (export const prerender = false) -- it will not work on a static build; requires the Astro server runtime
  • No password field -- the login is email-only; authentication logic is server-side
  • The form uses a standard <form> element with submit event, so browser-native validation (required, type="email") applies before JS runs
  • The finally block always re-enables the button and resets text to "Sign in", even after errors
  • Server-side auth check redirects to /portal before page render -- you cannot see the login page while authenticated
  • The submit handler uses e.preventDefault() to stop native form submission and handle it via fetch
  • Redirect URL comes from server response (data.redirect) with /portal as fallback
  • Tailwind CSS classes are used throughout -- unlike /connect which uses inline styles

Gotchas

  • SSR requirement: Accessing /login on a statically built site returns a blank page or error -- the page requires prerender = false and a running Astro server
  • No password field: Unlike /connect, this form has no password input -- do not look for or try to fill a password field
  • Browser validation fires first: The required attribute on input#email causes browser-native validation before the JS submit handler runs; automation tools that bypass form validation may skip this check
  • Auth redirect is server-side: The Astro.locals.auth check and Astro.redirect('/portal') happen during SSR -- there is no client-side redirect for already-authenticated users; the page simply never renders
  • Error message reuse: The same #error-message div handles both server errors and network errors; its content is overwritten each time -- there is no separate element for different error types
  • Button state always resets: The finally block re-enables the button even on success, but window.location.href assignment navigates away before the user sees it; in slow-redirect scenarios the button may briefly flash back to "Sign in"