Skip to content

Code Organization

This guide outlines the architectural principles and conventions used to organize the Bagisto Headless codebase, ensuring maintainability and scalability.

1. Directory Structure

The project follows a modular, feature-based organization. All source code resides in the src/ directory.

bash
src/
├── app/            # Next.js App Router (Routes, Layouts, APIs)
├── components/     # UI Components (Organized by domain: catalog, checkout, etc.)
├── graphql/        # GraphQL Operations (Queries, Mutations, Fragments)
├── lib/            # Core library configurations (Apollo, Graphql-fetch)
├── providers/      # React Context Providers (Store, Theme, Auth)
├── store/          # Redux Toolkit (Slices, Store configuration)
├── types/          # Global TypeScript definitions
└── utils/          # Shared Helpers and Custom Hooks

2. Naming Conventions

Consistency in naming makes the codebase predictable and easier to navigate.

Components

All React components use PascalCase and are stored in .tsx files.

  • Example: ProductCard.tsx, MiniCart.tsx

Hooks

Custom hooks use camelCase and must start with the use prefix.

  • Example: useAddToCart.ts, useCheckout.ts

Utilities & Helpers

General utility functions use camelCase.

  • Example: helper.ts, type-guards.ts

TypeScript Types

Interfaces and types use PascalCase.

  • Example: AddressDataTypes, BagistoCart

3. Import Organization

The project uses TypeScript Path Aliases to avoid complex relative paths (e.g., ../../../). This makes moving files easier and imports cleaner.

Defined Aliases:

  • @/ -> src/
  • @components/ -> src/components/
  • @utils/ -> src/utils/

Example:

typescript
import { ProductCard } from "@components/catalog/product/ProductCard";
import { useAddToCart } from "@utils/hooks/useAddToCart";

4. Code Splitting

To optimize performance and reduce initial bundle sizes, we utilize Next.js Dynamic Imports for components that are not required for the initial paint.

Implementation:

tsx
import dynamic from "next/dynamic";

const OrderDetail = dynamic(() => import("@/components/cart/OrderDetail"), {
  loading: () => <Skeleton />,
});

Commonly used for:

  • Heavy sidebar/drawer components.
  • Success pages.
  • Complex review sections in checkout.

5. Domain-Driven Design

Data and UI are grouped by their business domain (e.g., cart, catalog, checkout). Each domain typically has its own:

  1. GraphQL Operations: src/graphql/[domain]
  2. Components: src/components/[domain]
  3. Redux State: src/store/slices/[domain]-slice.ts

Next Steps

Released under the MIT License.