Skip to main content

webf-routing-setup

Setup hybrid routing with native screen transitions in WebF - configure navigation using WebF routing instead of SPA routing. Use when setting up navigation, implementing multi-screen apps, or when react-router-dom/vue-router doesn't work as expected.

소스 정보

저장소
openwebf/webf
최근 소스 활동
2026년 3월 29일 15:12
감지된 SKILL.md 언어
영어
스타
2,514
포크
163

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

파일 탐색기
3 개 파일

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
webf-routing-setup
description
Setup hybrid routing with native screen transitions in WebF - configure navigation using WebF routing instead of SPA routing. Use when setting up navigation, implementing multi-screen apps, or when react-router-dom/vue-router doesn't work as expected.
# WebF Routing Setup > **Note**: WebF development is nearly identical to web development - you use the same tools (Vite, npm, Vitest), same frameworks (React, Vue, Svelte), and same deployment services (Vercel, Netlify). This skill covers **one of the 3 key differences**: routing with native screen transitions instead of SPA routing. The other two differences are async rendering and API compatibility. **WebF does NOT use traditional Single-Page Application (SPA) routing.** Instead, it uses **hybrid routing** where each route renders on a separate, native Flutter screen with platform-native transitions. ## The Fundamental Difference ### In Browsers (SPA Routing) Traditional web routing uses the History API or hash-based routing: ```javascript // Browser SPA routing (react-router-dom, vue-router) // ❌ This pattern does NOT work in WebF import { BrowserRouter, Routes, Route } from 'react-router-dom'; // Single page with client-side routing // All routes render in the same screen // Transitions are CSS-based ``` The entire app runs in one screen, and route changes are simulated with JavaScript and CSS. ### In WebF (Hybrid Routing) Each route is a separate Flutter screen with native transitions: ```javascript // WebF hybrid routing // ✅ This pattern WORKS in WebF import { Routes, Route, WebFRouter } from '@openwebf/react-router'; // Each route renders on a separate Flutter screen // Transitions use native platform animations // Hardware back button works correctly ``` **Think of it like native mobile navigation** - each route is a new screen in a navigation stack, not a section of a single web page. ## Why Hybrid Routing? WebF's approach provides true native app behavior: 1. **Native Transitions** - Platform-specific animations (Cupertino for iOS, Material for Android) 2. **Proper Lifecycle** - Each route has its own lifecycle, similar to native apps 3. **Hardware Back Button** - Android back button works correctly 4. **Memory Management** - Unused routes can be unloaded 5. **Deep Linking** - Integration with platform deep linking 6. **Synchronized Navigation** - Flutter Navigator and WebF routing stay in sync ## React Setup ### Installation ```bash npm install @openwebf/react-router ``` **CRITICAL**: Do NOT use `react-router-dom` - it will not work correctly in WebF. ### Basic Route Configuration ```jsx import { Route, Routes } from '@openwebf/react-router'; import { HomePage } from './pages/home'; import { ProfilePage } from './pages/profile'; import { SettingsPage } from './pages/settings'; function App() { return ( <Routes> {/* Each Route must have a title prop */} <Route path="/" element={<HomePage />} title="Home" /> <Route path="/profile" element={<ProfilePage />} title="Profile" /> <Route path="/settings" element={<SettingsPage />} title="Settings" /> </Routes> ); } export default App; ``` **Important**: The `title` prop appears in the native navigation bar for that screen. ### Programmatic Navigation Use the `WebFRouter` object for navigation: ```jsx import { WebFRouter } from '@openwebf/react-router'; function HomePage() { // Navigate forward (push new screen) const goToProfile = () => { WebFRouter.pushState({ userId: 123 }, '/profile'); }; // Replace current screen (no back button) const replaceWithSettings = () => { WebFRouter.replaceState({}, '/settings'); }; // Navigate back const goBack = () => { WebFRouter.back(); }; // Navigate forward const goForward = () => { WebFRouter.forward(); }; return ( <div> <h1>Home Page</h1> <button onClick={goToProfile}>View Profile</button> <button onClick={replaceWithSettings}>Go to Settings</button> <button onClick={goBack}>Back</button> <button onClick={goForward}>Forward</button> </div> ); } ``` ### Passing Data Between Routes Use the state parameter to pass data: ```jsx import { WebFRouter, useLocation } from '@openwebf/react-router'; // Sender component function ProductList() { const viewProduct = (product) => { // Pass product data to detail screen WebFRouter.pushState({ productId: product.id, productName: product.name, productPrice: product.price }, '/product/detail'); }; return ( <div> <button onClick={() => viewProduct({ id: 1, name: 'Widget', price: 19.99 })}> View Product </button> </div> ); } // Receiver component function ProductDetail() { const location = useLocation(); const { productId, productName, productPrice } = location.state || {}; if (!productId) { return <div>No product data</div>; } return ( <div> <h1>{productName}</h1> <p>Price: ${productPrice}</p> <p>ID: {productId}</p> </div> ); } ``` ### Using Route Parameters WebF supports dynamic route parameters: ```jsx import { Route, Routes, useParams } from '@openwebf/react-router'; function App() { return ( <Routes> <Route path="/" element={<HomePage />} title="Home" /> <Route path="/user/:userId" element={<UserProfile />} title="User Profile" /> <Route path="/post/:postId/comment/:commentId" element={<CommentDetail />} title="Comment" /> </Routes> ); } function UserProfile() { const { userId } = useParams(); return ( <div> <h1>User Profile</h1> <p>User ID: {userId}</p> </div> ); } function CommentDetail() { const { postId, commentId } = useParams(); return ( <div> <h1>Comment Detail</h1> <p>Post ID: {postId}</p> <p>Comment ID: {commentId}</p> </div> ); } ``` ### Declarative Navigation with Links Use `WebFRouterLink` for clickable navigation: ```jsx import { WebFRouterLink } from '@openwebf/react-router'; function NavigationMenu() { return ( <nav> <WebFRouterLink path="/" title="Home"> <button>Home</button> </WebFRouterLink> <WebFRouterLink path="/profile" title="My Profile"> <button>Profile</button> </WebFRouterLink> <WebFRouterLink path="/settings" title="Settings" onScreen={() => console.log('Link is visible')} > <button>Settings</button> </WebFRouterLink> </nav> ); } ``` ### Advanced Navigation Methods WebFRouter provides Flutter-style navigation for complex scenarios: ```jsx import { WebFRouter } from '@openwebf/react-router'; // Push a route (async, returns when screen is pushed) await WebFRouter.push('/details', { itemId: 42 }); // Replace current route (no back button) await WebFRouter.replace('/login', { sessionExpired: true }); // Pop and push (remove current, add new) await WebFRouter.popAndPushNamed('/success', { orderId: 'ORD-123' }); // Check if can pop if (WebFRouter.canPop()) { const didPop = WebFRouter.maybePop({ cancelled: false }); console.log('Did pop:', didPop); } // Restorable navigation (state restoration support) const restorationId = await WebFRouter.restorablePopAndPushNamed('/checkout', { cartItems: items, timestamp: Date.now() }); ``` ## Hooks API WebF routing provides React hooks for accessing route information: ```jsx import { useLocation, useParams, useNavigate } from '@openwebf/react-router'; function MyComponent() { // Get current location (pathname, state, etc.) const location = useLocation(); console.log('Current path:', location.pathname); console.log('Route state:', location.state); // Get route parameters const { userId, postId } = useParams(); // Get navigation function const navigate = useNavigate(); const handleClick = () => { // Navigate programmatically navigate('/profile', { userId: 123 }); }; return <button onClick={handleClick}>Go to Profile</button>; } ``` ## Common Patterns ### Pattern 1: Protected Routes Redirect to login if not authenticated: ```jsx import { useEffect } from 'react'; import { WebFRouter, useLocation } from '@openwebf/react-router'; function ProtectedRoute({ children, isAuthenticated }) { const location = useLocation(); useEffect(() => { if (!isAuthenticated) { // Redirect to login, save current path WebFRouter.pushState({ redirectTo: location.pathname }, '/login'); } }, [isAuthenticated, location.pathname]); if (!isAuthenticated) { return null; // Or loading spinner } return children; } // Usage function App() { const [isAuthenticated, setIsAuthenticated] = useState(false); return ( <Routes> <Route path="/login" element={<LoginPage />} title="Login" /> <Route path="/dashboard" element={ <ProtectedRoute isAuthenticated={isAuthenticated}> <DashboardPage /> </ProtectedRoute> } title="Dashboard" /> </Routes> ); } ``` ### Pattern 2: Redirecting After Login After successful login, navigate to saved location: ```jsx function LoginPage() { const location = useLocation(); const redirectTo = location.state?.redirectTo || '/'; const handleLogin = async () => { // Perform login await loginUser(); // Redirect to saved location or home WebFRouter.replaceState({}, redirectTo); }; return ( <button onClick={handleLogin}> Login </button> ); } ``` ### Pattern 3: Conditional Navigation Navigate based on result: ```jsx async function handleSubmit(formData) { try { const result = await submitForm(formData); if (result.success) { // Navigate to success page WebFRouter.pushState({ message: result.message, orderId: result.orderId }, '/success'); } else { // Navigate to error page WebFRouter.pushState({ error: result.error }, '/error'); } } catch (error) { // Handle error WebFRouter.pushState({ error: error.message }, '/error'); } } ``` ### Pattern 4: Preventing Navigation Confirm before leaving unsaved changes: ```jsx import { useEffect } from 'react'; import { WebFRouter } from '@openwebf/react-router'; function FormPage() { const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false); useEffect(() => { if (!hasUnsavedChanges) return; // Custom back button handler const handleBack = () => { const shouldLeave = confirm('You have unsaved changes. Leave anyway?'); if (shouldLeave) { setHasUnsavedChanges(false); WebFRouter.back(); } }; // Note: This is a simplified example // Actual implementation depends on your back button handling }, [hasUnsavedChanges]); return ( <form onChange={() => setHasUnsavedChanges(true)}> {/* Form fields */} </form> ); } ``` ## Vue Setup For Vue applications, use `@openwebf/vue-router`: ```bash npm install @openwebf/vue-router ``` **Note**: The API is similar to Vue Router but adapted for WebF's hybrid routing. Full Vue examples are available in `examples.md`. ## Cross-Platform Support For apps that run in both WebF and browsers, see `cross-platform.md` for router adapter patterns. ## Key Differences from SPA Routing | Feature | SPA Routing (Browser) | Hybrid Routing (WebF) |
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기