Install
$ agentstack add skill-ggombee-code-forge-react-spa ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
React SPA 컨벤션
이 프로젝트는 Vite 또는 CRA(Create React App) 기반의 React SPA다.
프로젝트 구조
src/
├── main.tsx # 진입점
├── App.tsx # 루트 컴포넌트
├── routes/ # 라우트 정의
│ └── index.tsx
├── pages/ # 페이지 컴포넌트
│ ├── HomePage.tsx
│ └── OrderPage.tsx
├── components/ # 공유 컴포넌트
├── hooks/ # 커스텀 훅
├── services/ # API 서비스
├── store/ # 상태 관리
├── types/ # TypeScript 타입
└── utils/ # 유틸리티 함수
Vite 설정
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
},
server: {
port: 3000,
proxy: {
'/api': {
target: process.env.VITE_API_URL,
changeOrigin: true,
},
},
},
});
진입점
// src/main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import App from './App';
import './index.css';
const queryClient = new QueryClient();
ReactDOM.createRoot(document.getElementById('root')!).render(
,
);
react-router-dom v6 라우팅
기본 라우트 설정
// src/routes/index.tsx
import { Routes, Route, Navigate } from 'react-router-dom';
import { Suspense, lazy } from 'react';
// 코드 스플리팅
const HomePage = lazy(() => import('@/pages/HomePage'));
const OrderPage = lazy(() => import('@/pages/OrderPage'));
const OrderDetailPage = lazy(() => import('@/pages/OrderDetailPage'));
const NotFoundPage = lazy(() => import('@/pages/NotFoundPage'));
export function AppRoutes() {
return (
로딩 중...}>
} />
} />
} />
} />
} />
);
}
중첩 라우트
// src/routes/index.tsx
import { Outlet } from 'react-router-dom';
function DashboardLayout() {
return (
대시보드 메뉴
{/* 자식 라우트가 렌더링되는 위치 */}
);
}
export function AppRoutes() {
return (
}>
} /> {/* /dashboard */}
} /> {/* /dashboard/orders */}
} /> {/* /dashboard/settings */}
);
}
보호된 라우트
// src/routes/ProtectedRoute.tsx
import { Navigate, Outlet } from 'react-router-dom';
import { useAuthStore } from '@/store/auth';
export function ProtectedRoute() {
const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
if (!isAuthenticated) {
return ;
}
return ;
}
라우트 훅 사용
import { useNavigate, useParams, useSearchParams, useLocation } from 'react-router-dom';
function OrderDetailPage() {
const { orderId } = useParams();
const navigate = useNavigate();
const [searchParams, setSearchParams] = useSearchParams();
const location = useLocation();
const handleBack = () => navigate(-1);
const handleGoToOrders = () => navigate('/orders');
// 쿼리 파라미터
const page = searchParams.get('page') ?? '1';
return 주문 #{orderId};
}
환경 변수 (Vite)
// .env.local
VITE_API_URL=http://localhost:8080
VITE_ENV=development
// 코드에서 사용
const apiUrl = import.meta.env.VITE_API_URL;
const isDev = import.meta.env.DEV; // Vite 내장 변수
// ❌ process.env는 Vite에서 동작하지 않음
const url = process.env.REACT_APP_API_URL; // CRA 방식
// ✅ Vite 방식
const url = import.meta.env.VITE_API_URL;
빌드 설정
// package.json
{
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"lint": "eslint src --ext ts,tsx",
"test": "vitest"
}
}
App.tsx 구조
// src/App.tsx
import { AppRoutes } from '@/routes';
function App() {
return ;
}
export default App;
체크리스트
- [ ] 코드 스플리팅에
lazy()+Suspense사용? - [ ] 환경 변수는
VITE_접두사 사용 (Vite)? - [ ] 중첩 라우트에
Outlet사용? - [ ] 보호된 라우트에
ProtectedRoute래퍼 사용? - [ ] 존재하지 않는 경로는 404 페이지로 리다이렉트?
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: ggombee
- Source: ggombee/code-forge
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.