How the Sub2API Frontend Is Structured: A Complete Vue 3 Architecture Guide

TLDR: The Sub2API frontend is a modular Vue 3 single-page application built with Vite, organized into focused layers — routing, Pinia stores, a typed API wrapper, reusable components, composables, and utilities — all configured under a single frontend/ directory in the Wei-Shaw/sub2api repository.

The Sub2API frontend follows a clean, layered architecture that separates concerns across routing, state management, API communication, and UI components. This guide walks through each structural layer, references the exact source files, and shows how they fit together — giving you a practical map of the Vue 3 codebase as implemented in the frontend/ directory of the Wei-Shaw/sub2api repository.

Root Configuration and Build Setup

Every Vue 3 application starts with its build tooling, and Sub2API configures everything through standard Vite and TypeScript configuration files at the frontend's root.

The key files in this layer include vite.config.ts (build and dev server), tsconfig.json (TypeScript checking), tailwind.config.js (utility-first styling), and vitest.config.ts (unit testing). These four files define how the rest of the frontend compiles, styles, and validates code.

The Application Entry Point: main.ts

Bootstrap logic lives in src/main.ts, where the Vue app is created, plugins are registered, and the root component is mounted. This is the exact bootstrap flow as implemented in the source:

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { createPinia } from 'pinia'

const app = createApp(App)
app.use(createPinia())
app.use(router)
app.mount('#app')

The app wires in Pinia for state management and the Vue Router for navigation before mounting the root component App.vue.

Root Component and Routing Layer

The src/App.vue file serves as the top-level layout, hosting the <router-view> outlet and global UI elements like toast notifications.

Routing is handled declaratively through several dedicated modules:

Route guards protect sensitive pages, while the title module keeps the browser tab in sync with the current view. This modular approach keeps navigation logic testable and easy to extend.

State Management with Pinia Stores

All mutable application state in Sub2API lives in dedicated Pinia stores under src/stores/. Each domain gets its own store file:

Here is how a component consumes a store via the Composition API, as seen in src/views/user/DashboardView.vue:

<script setup lang="ts">
import { useSubscriptionsStore } from '@/stores/subscriptions'
const subsStore = useSubscriptionsStore()
await subsStore.fetchSubscriptions()
</script>

Storing all mutable state in Pinia keeps data predictable and makes the stores independently testable — the repository includes test specs alongside each store.

Typed API Layer with Axios

The frontend communicates with the backend through a thin wrapper layer in src/api/. Each wrapper returns typed promises, so components never deal with raw request plumbing.

Key files include:

A typical component call looks like this from src/components/user/profile/ProfileInfoCard.vue:

<script setup lang="ts">
import { api } from '@/api/client'
const { data, error } = await api.auth.getProfile()
</script>

Centralized error handling is implemented in src/utils/apiError.ts, ensuring every failed request surfaces a consistent, user-friendly error.

Views and Reusable Components

The UI is organized into two complementary directories.

Views (Pages)

src/views/ groups full pages by feature area: user/ for the dashboard and profile, setup/ for onboarding flows, and public/ for public-facing routes. Each view file maps to one top-level router route, for example views/user/DashboardView.vue.

Reusable Components

src/components/ contains small, focused building blocks segmented by domain:

  • common/ — shared UI like Toast.vue and LoadingSpinner.vue
  • auth/ — login and registration widgets
  • user/profile/ — profile cards and settings
  • user/monitor/ — monitoring views
  • keys/ and channels/ — feature-specific components
  • charts/ — data visualization components

This tiny component design promotes reuse and keeps each Vue file readable.

Composables and Utilities

Business logic that spans multiple components is extracted into composables under src/composables/. Examples include useTableLoader, useAutoRefresh, and useOpenAIOAuth, enables components to pull in logic via Composition API composables.

<script setup lang="ts">
import { useAutoRefresh } from '@/composables/useAutoRefresh'
useAutoRefresh(30_000) // refresh every 30 seconds
</script>

Supporting utilities live in:

  • src/utils/ — helper functions like apiError.ts
  • src/types/ — TypeScript type definitions
  • src/constants/ — platform constants and helpers (platforms.ts)
  • src/assets/ — static files such as logos and screenshots

Styling and Theming

Global styling relies on Tailwind CSS, configured in tailwind.config.js. The design system is enforced through utility components like PlatformIcon.vue and StatusBadge.vue, which apply consistent theming and patterns across all pages.

Testing

Unit tests sit alongside the modules they cover using Vitest. Each Pinia store has a companion test file under src/stores/__tests__/*.spec.ts, and router logic is covered in src/router/__tests__/*.spec.ts, ensuring that state transitions and navigation guard behavior stay correct as the project grows.

Summary

The Sub2API frontend is a well-organized Vue 3 application that separates concerns cleanly through a layered architecture:

  • Build tools (Vite, TypeScript, Tailwind) are configured at the repo root under frontend/.
  • Routing is declarative with multiple helper modules for metadata, titles, and redirects.
  • State is isolated into dedicated Pinia stores per domain.
  • API communication goes through a typed wrapper layer built on Axios.
  • UI components are reusable and grouped by domain for easy maintenance.
  • Composables and utilities keep business logic reusable throughout the app.

Frequently Asked Questions

What is the frontend stack of Sub2API?

The Sub2API frontend runs on Vue 3 with Vite as the build tool, TypeScript for static typing, Pinia for state management, Vue Router for navigation, and Tailwind CSS for styling. Unit tests are written with Vitest.

How does the Sub2API frontend handle API requests?

All HTTP communication goes through a centralized Axios client defined in src/api/client.ts, with interceptors for auth and error handling. Domain-specific modules like src/api/auth.ts and src/api/groups.ts wrap the endpoints and return typed promises so components can simply await api.auth.login(...) without request plumbing.

Where does the Sub2API store user authentication state?

Auth state lives in the dedicated Pinia store at src/stores/auth.ts. Components and router guards read and mutate authentication status exclusively through this store, which keeps auth logic predictable and testable.

How are UI components organized in Sub2API?

Components under src/components/ are divided by domain — common/ for shared elements, auth/ for login forms, user/ for profile and monitoring, plus separate folders for keys, channels, and charts. This domain-based grouping allows developers to locate and reuse components quickly.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →