Client Portal Application
The client.schwab.com application serves as Charles Schwab's secure, authenticated client portal, providing existing customers with protected access to their accounts, financial tools, and personalized services. This mission-critical application implements enterprise-grade security measures and user authentication to safeguard sensitive financial information and enable comprehensive account management capabilities.
Overview
- Application:
apps/client.schwab.com - Port: 3001
- Version: 1.0.15
- Framework: Next.js 15.3.2 with App Router
- Purpose: Authenticated client portal and account management
- Access: Secured client portal requiring authentication
Key Features
- Secure Authentication: Enterprise-grade client authentication system
- Account Management: Comprehensive client account access and management
- Dynamic Routing: Code-based routing for personalized client experiences
- Security Middleware: Multi-layer security including authentication, nonces, and redirects
- Feature Flags: A/B testing and controlled feature rollouts
- Font Integration: Charles Schwab branded typography with Charles Modern font family
- Responsive Design: Tailwind CSS with mobile-optimized interface
- Performance Monitoring: Vercel Analytics and Speed Insights integration
Technical Architecture
Framework Stack
| Technology | Version | Purpose |
|---|---|---|
| Next.js | 15.3.2 | React framework with App Router and server components |
| React | 19.1.0 | Component library with React Aria integration |
| TypeScript | 5.8.2 | Type safety and enhanced development experience |
| Tailwind CSS | 4.0.17 | Utility-first styling system |
| Adobe React Spectrum | 3.40.1 | Design system and accessibility components |
| Sass | 1.86.1 | CSS preprocessing for advanced styling |
Core Dependencies
{
"@adobe/react-spectrum": "^3.40.1",
"@schwab/beacon-design-tokens": "^1.24.29",
"@schwab/fetch": "workspace:*",
"@schwab/ui": "workspace:*",
"@schwab/utilities": "workspace:*",
"@schwab/schema": "workspace:*",
"@vercel/analytics": "^1.5.0",
"@vercel/edge-config": "^1.4.0",
"@vercel/toolbar": "^0.1.36",
"@vercel/speed-insights": "^1.2.0",
"nanoid": "^5.1.5",
"react-aria": "^3.38.1"
}
Monorepo Integration
The application leverages comprehensive internal packages:
@schwab/ui: Shared React component library@schwab/fetch: HTTP client utilities and authentication@schwab/utilities: Common utility functions and helpers@schwab/schema: Data validation and type definitions@schwab/beacon-design-tokens: Charles Schwab design system tokens@schwab/twconfig: Shared Tailwind CSS configuration
Directory Structure
apps/client.schwab.com/
├── src/
│ ├── app/ # App Router directory (Next.js 13+)
│ │ ├── [code]/ # Dynamic route for client-specific content
│ │ │ ├── @globalFooter/ # Parallel route for footer component
│ │ │ │ └── default.tsx # Default footer implementation
│ │ │ ├── @globalHeader/ # Parallel route for header component
│ │ │ │ └── default.tsx # Default header implementation
│ │ │ ├── secured-test/ # Secured testing routes
│ │ │ └── layout.tsx # Client-specific layout
│ │ ├── api/ # API route handlers
│ │ │ ├── health-check/ # Application health monitoring
│ │ │ │ └── route.ts # Health check endpoint
│ │ │ ├── revalidate/ # Cache revalidation endpoints
│ │ │ └── route.ts # Main API route handler
│ │ └── global.css # Global CSS styles
│ ├── flags/ # Feature flag configuration
│ │ ├── flags/ # Individual flag definitions
│ │ └── index.ts # Flag exports and utilities
│ ├── global/ # Global assets and utilities
│ │ ├── icons.scss # Icon definitions and styles
│ │ ├── styles.scss # Global SCSS styles
│ │ └── windowDataLayer.tsx # Analytics data layer
│ ├── middlewares/ # Middleware functions
│ │ ├── chain.ts # Middleware chain orchestration
│ │ ├── get-or-generate-visitor-id.ts # Visitor tracking
│ │ ├── withClientAuthentication.ts # Authentication middleware
│ │ ├── withFlags.ts # Feature flag middleware
│ │ ├── withNonce.ts # Security nonce generation
│ │ └── withRedirects.ts # Redirect handling
│ └── middleware.ts # Next.js middleware configuration
├── public/ # Static assets
│ ├── assets/ # General static assets
│ ├── fonts/ # Charles Schwab branded fonts
│ │ ├── CharlesModern-*.woff # Charles Modern font variants
│ │ └── Schwab-Icon-Font.woff # Schwab icon font
│ ├── ira-poc/ # IRA proof-of-concept assets
│ ├── favicon.ico # Application favicon
│ └── test-img.png # Test image asset
├── .allowlists/ # Security allowlist configurations
├── next.config.js # Next.js configuration
├── package.json # Package dependencies and scripts
├── postcss.config.js # PostCSS configuration
└── tsconfig.json # TypeScript configuration
Authentication Architecture
Multi-Layer Security Middleware
export default chainMiddleware([
withClientAuthentication,
withRedirects,
withFlags,
withNonce
]);
Client Authentication System
export const withClientAuthentication: MiddlewareFactory = (next) => {
return async (request: NextRequest, event: NextFetchEvent) => {
if (!request.nextUrl.origin.includes('localhost')) {
const isValidCookie = isCookieValid(request);
if (!isValidCookie) {
return redirectToLogin(request, 'INVALID COOKIE');
}
const isAuthenticated = await isUserAuthenticated(request);
if (!isAuthenticated) {
return redirectToLogin(request, 'NOT AUTHENTICATED');
}
}
return next(request, event);
};
};
Authentication Flow
Cookie Validation
function isCookieValid(request: NextRequest): boolean {
const authCookie = request.cookies.get('auth');
return !!authCookie;
}
async function isUserAuthenticated(request: NextRequest): Promise<boolean> {
if (!request.cookies) {
return false;
}
var response = await isRequestAuthenticated(request.cookies.toString());
return response.isOk;
}
Dynamic Routing Architecture
Code-Based Routing System
The application uses a [code] dynamic route for personalized client experiences:
export default async function RootLayout({
children,
globalHeader,
globalFooter,
}: {
children: React.ReactNode;
globalHeader: React.ReactNode;
globalFooter: React.ReactNode;
}) {
return (
<html
className={`${charlesModern.className} ${schwabIcon.variable}`}
lang="en"
suppressHydrationWarning={true}
>
<body>
{globalHeader}
<main id="content--main">{children}</main>
{globalFooter}
</body>
</html>
);
}
Font Integration System
const charlesModern = localFont({
src: [
{
path: '../../../public/fonts/CharlesModern-Bold.woff',
weight: '700',
style: 'normal',
},
{
path: '../../../public/fonts/CharlesModern-Regular.woff',
weight: '400',
style: 'normal',
},
{
path: '../../../public/fonts/CharlesModern-Light.woff',
weight: '300',
style: 'normal',
},
],
display: 'swap',
});
const schwabIcon = localFont({
src: [
{
path: '../../../public/fonts/Schwab-Icon-Font.woff',
weight: '700',
style: 'normal',
},
],
display: 'swap',
variable: '--schwabIcon',
});
Feature Flag System
Dynamic Flag Management
import { requireAll } from '@schwab/utilities/flags';
export const allFlags = [
...requireAll(require.context('./flags', true, /\.ts$/))
] as const;
Features:
- Client-Specific Features: Personalized feature rollouts
- A/B Testing: Controlled user experience experiments
- Progressive Deployment: Gradual feature releases
- Emergency Controls: Rapid feature disable capabilities
Security Configuration
Next.js Security Headers
async headers() {
return [
{
source: '/:path*',
headers: [
{
key: 'Strict-Transport-Security',
value: 'max-age=63072000; includeSubDomains; preload',
},
{ key: 'X-Frame-Options', value: 'SAMEORIGIN' },
{ key: 'Referrer-Policy', value: 'origin-when-cross-origin' },
{ key: 'X-Content-Type-Options', value: 'nosniff' },
],
},
];
}
API CORS Configuration
{
source: '/api/:path*',
headers: [
{ key: 'Access-Control-Allow-Credentials', value: 'true' },
{ key: 'Access-Control-Allow-Origin', value: '*' },
{ key: 'Access-Control-Allow-Methods', value: 'GET,OPTIONS' },
{
key: 'Access-Control-Allow-Headers',
value: 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version,x-vercel-protection-bypass,correlatorid,schwab-client-appid,schwab-client-channel,schwab-client-correlid,schwab-environment,schwab-environment-region',
},
],
}
Request Filtering
export const config = {
matcher: [
'/((?!api|_next/static|_next/image|favicon.ico|robots.txt|nextassets|bundle|Areas|.well-known|_vercel|.js|.css|.css.map).*)',
],
};
Development Workflow
Local Development
# Install dependencies
pnpm install
# Start development server on port 3001
pnpm dev
# Build for production
pnpm build
# Start production server
pnpm start
# Type checking
pnpm type-check
# Code conformance checking
pnpm conformance
Package Transpilation
Comprehensive Adobe React Spectrum transpilation:
transpilePackages: [
'@adobe/react-spectrum',
'@react-spectrum/actiongroup',
'@react-spectrum/badge',
'@react-spectrum/breadcrumbs',
'@react-spectrum/button',
// ... 40+ additional Spectrum packages
'@spectrum-icons/illustrations',
'@spectrum-icons/ui',
'@spectrum-icons/workflow',
]
Image Optimization
Remote Pattern Configuration
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'prospectsitecollection.uat-schwab.acsitefactory.com',
port: '',
pathname: '**',
},
{
protocol: 'https',
hostname: 'education.uat-schwab.acsitefactory.com',
port: '',
pathname: '**',
},
{
protocol: 'https',
hostname: 'education-uat.dev.schwab.tech',
port: '',
pathname: '**',
},
{
protocol: 'https',
hostname: 'education.dev-schwab.acsitefactory.com',
port: '',
pathname: '**',
},
],
}
API Architecture
Health Check Monitoring
export function GET() {
return new Response(JSON.stringify(getAppVersion(packageJSON.name)), {
status: 200,
});
}
Cache Revalidation
- Dynamic Cache Management: On-demand cache invalidation
- Content Freshness: Real-time content updates
- Performance Optimization: Intelligent caching strategies
Client Portal Features
Secure Access Control
| Feature | Implementation | Purpose |
|---|---|---|
| Authentication Middleware | Cookie and API validation | Secure user verification |
| Redirect Management | Automatic login redirection | Seamless authentication flow |
| Session Management | Visitor ID generation | User session tracking |
| Nonce Security | Cryptographic nonce generation | CSRF protection |
Personalized Experience
Performance Optimization
Next.js Configuration
const nextConfig = {
experimental: {
useCache: true, // Enable advanced caching
},
reactStrictMode: true, // Enhanced development checks
trailingSlash: false, // Clean URL structure
}
Analytics Integration
- Vercel Analytics: Real user monitoring and performance insights
- Speed Insights: Core Web Vitals tracking and optimization
- Edge Configuration: Dynamic configuration management
- Custom Analytics: Client-specific usage tracking
Middleware Chain Architecture
Chain Orchestration
import { chainMiddleware } from './middlewares/chain';
// Middleware execution order is critical for security
export default chainMiddleware([
withClientAuthentication, // 1. Verify user authentication
withRedirects, // 2. Handle URL redirects
withFlags, // 3. Evaluate feature flags
withNonce // 4. Generate security nonces
]);
Visitor Tracking
- Unique ID Generation: nanoid-based visitor identification
- Cross-Session Tracking: Persistent visitor analytics
- Privacy Compliance: GDPR-compliant tracking mechanisms
Testing and Quality Assurance
Development Dependencies
{
"@jest/globals": "^29.7.0",
"@schwab/mock-data": "workspace:*",
"@testing-library/react": "^16.2.0",
"@vercel-private/conformance": "^1.12.4",
"jest-mock-extended": "^3.0.7",
"ts-node": "^10.9.2"
}
Quality Standards
- TypeScript: Strict type checking and IDE integration
- Vercel Conformance: Enterprise code quality standards
- Jest Testing: Comprehensive unit and integration testing
- React Testing Library: Component testing utilities
Common Use Cases
Authenticated Client Flow
// 1. Client accesses portal
// 2. Authentication middleware validates session
// 3. Dynamic route loads personalized content
// 4. Feature flags customize experience
// 5. Analytics track user engagement
const clientPortalFlow = async (request: NextRequest) => {
// Validate authentication
const isAuthenticated = await isUserAuthenticated(request);
// Load client-specific features
const features = await evaluateFeatureFlags(clientId);
// Render personalized content
return renderClientDashboard(features);
};
Security Validation
// Cookie validation
const isValidCookie = isCookieValid(request);
// API authentication check
const isAuthenticated = await isRequestAuthenticated(cookies);
// Nonce generation for CSP
const nonce = generateSecurityNonce();
// Redirect management
const redirectUrl = processRedirects(pathname);
Integration Patterns
CXP Integration
| Component | Integration | Purpose |
|---|---|---|
| Authentication | CXP Monolith/Alto APIs | User session validation |
| Client Data | Internal APIs | Account information retrieval |
| Security | Enterprise security stack | Multi-layer protection |
| Analytics | Vercel + Custom | Performance and usage tracking |
External Service Integration
- Adobe Spectrum: Design system and accessibility
- Vercel Platform: Deployment, analytics, and edge configuration
- Charles Schwab APIs: Account data and business services
- CXP Authentication: Enterprise authentication system
Troubleshooting
Common Issues
| Issue | Cause | Solution |
|---|---|---|
| Port 3001 in use | Previous process running | Use kill script in dev command |
| Authentication failures | Invalid/expired cookies | Clear cookies and re-authenticate |
| Spectrum components not rendering | Missing Provider wrapper | Ensure Provider configuration |
| TypeScript errors | Missing type definitions | Run pnpm type-check |
| Font loading issues | Incorrect font paths | Verify local font configuration |
| Middleware errors | Chain order issues | Check middleware sequence |
Security Debugging
Never disable authentication middleware in non-localhost environments. This could expose sensitive client data.
Use Vercel Speed Insights to monitor Core Web Vitals and identify performance bottlenecks in the client portal.
Future Enhancements
- Enhanced Personalization: AI-driven content recommendations
- Advanced Security: Multi-factor authentication integration
- Mobile App Integration: React Native companion application
- Real-time Features: WebSocket integration for live updates
- Advanced Analytics: Behavioral analysis and conversion tracking
- Accessibility Improvements: Enhanced screen reader and keyboard navigation
This client.schwab.com application serves as Charles Schwab's secure gateway for authenticated clients, providing enterprise-grade security, personalized experiences, and comprehensive account management capabilities while maintaining the highest standards of financial data protection and user privacy.