Routing and Multi-Page Apps =========================== BadGUI supports creating multi-page applications with Vue Router integration, allowing you to build complex single-page applications with client-side routing. Page Management --------------- Pages in BadGUI are created using the ``page()`` function, which acts as both a page definer and a context manager. Creating Pages ~~~~~~~~~~~~~~ .. code-block:: python import badgui as bg # Create a page with context manager with bg.page("/", "HomePage", "Home"): bg.label("Welcome to the Home Page") bg.label("This is the main landing page") **Parameters:** - ``path``: URL path (e.g., ``"/"``, ``"/about"``, ``"/contact"``) - ``name``: Component name (e.g., ``"HomePage"``, ``"AboutPage"``) - ``title``: Page title displayed in browser tab (optional) Page Context ~~~~~~~~~~~~ All components created within a page context are automatically added to that page: .. code-block:: python with bg.page("/about", "AboutPage", "About Us"): # These components belong to the About page bg.label("About Our Company") bg.label("Founded in 2025") with bg.row(): bg.label("Mission") bg.label("Vision") Navigation ---------- Link Component ~~~~~~~~~~~~~~ Create navigation between pages using the ``link()`` component: .. code-block:: python # Basic link bg.link("Go to About", "/about") # Styled as button bg.link("Contact Us", "/contact").classes("q-btn q-btn-primary") # With additional props bg.link("Home", "/").props("exact").classes("nav-link") **Generated Output:** ``Go to About`` Navigation Menu ~~~~~~~~~~~~~~~ Create a navigation menu across multiple pages: .. code-block:: python def create_nav(): \"\"\"Create consistent navigation menu.\"\"\" with bg.row().classes("q-gutter-md q-mb-lg justify-center") as nav: nav.classes("bg-primary text-white q-pa-md rounded") bg.link("Home", "/").classes("text-white no-underline q-btn q-btn-flat") bg.link("About", "/about").classes("text-white no-underline q-btn q-btn-flat") bg.link("Services", "/services").classes("text-white no-underline q-btn q-btn-flat") bg.link("Contact", "/contact").classes("text-white no-underline q-btn q-btn-flat") # Use in each page with bg.page("/", "HomePage", "Home"): create_nav() bg.label("Home Page Content") with bg.page("/about", "AboutPage", "About"): create_nav() bg.label("About Page Content") Route Parameters ---------------- Dynamic Routes ~~~~~~~~~~~~~~ Create routes with parameters: .. code-block:: python # Route with parameter with bg.page("/user/:id", "UserPage", "User Profile"): bg.label("User Profile Page") bg.label("User ID will be available in Vue component") # Navigation to dynamic route bg.link("View User 123", "/user/123") Nested Routes ~~~~~~~~~~~~~ Create nested route structures: .. code-block:: python # Parent route with bg.page("/dashboard", "DashboardPage", "Dashboard"): bg.label("Dashboard").classes("text-h3") # Navigation to child routes with bg.row().classes("q-gutter-md"): bg.link("Analytics", "/dashboard/analytics") bg.link("Settings", "/dashboard/settings") bg.link("Profile", "/dashboard/profile") # Child routes with bg.page("/dashboard/analytics", "AnalyticsPage", "Analytics"): bg.label("Analytics Dashboard") bg.label("View your analytics data here") with bg.page("/dashboard/settings", "SettingsPage", "Settings"): bg.label("Dashboard Settings") bg.input(placeholder="Setting 1") bg.input(placeholder="Setting 2") Multi-Page Application Example ------------------------------ Complete Blog Application ~~~~~~~~~~~~~~~~~~~~~~~~~~ Here's a complete multi-page blog application: .. code-block:: python import badgui as bg def create_header(): \"\"\"Create site header with navigation.\"\"\" with bg.row().classes("bg-primary text-white q-pa-md justify-between items-center") as header: bg.label("My Blog").classes("text-h5 text-weight-bold") with bg.row().classes("q-gutter-md"): bg.link("Home", "/").classes("text-white q-btn q-btn-flat") bg.link("Posts", "/posts").classes("text-white q-btn q-btn-flat") bg.link("About", "/about").classes("text-white q-btn q-btn-flat") bg.link("Contact", "/contact").classes("text-white q-btn q-btn-flat") def create_footer(): \"\"\"Create site footer.\"\"\" with bg.row().classes("bg-grey-8 text-white q-pa-lg justify-center q-mt-xl"): bg.label("© 2025 My Blog. All rights reserved.").classes("text-body2") # Home Page with bg.page("/", "HomePage", "My Blog - Home"): create_header() # Hero section with bg.column().classes("text-center q-pa-xl bg-gradient-to-r from-blue-500 to-purple-600 text-white"): bg.label("Welcome to My Blog").classes("text-h2 q-mb-md") bg.label("Sharing thoughts and ideas").classes("text-h6 q-mb-lg") bg.link("Read Latest Posts", "/posts").classes("q-btn q-btn-lg q-btn-white text-primary") # Featured posts with bg.column().classes("q-pa-xl"): bg.label("Featured Posts").classes("text-h4 q-mb-lg text-center") with bg.row().classes("q-col-gutter-lg"): for i in range(3): with bg.column().classes("col-12 col-md-4"): with bg.column().classes("bg-white rounded-lg shadow-2 q-pa-lg"): bg.label(f"Post Title {i+1}").classes("text-h6 q-mb-md") bg.label("Post excerpt goes here...").classes("text-body2 q-mb-md") bg.link("Read More", f"/post/{i+1}").classes("q-btn q-btn-primary") create_footer() # Posts Page with bg.page("/posts", "PostsPage", "All Posts"): create_header() with bg.column().classes("q-pa-xl"): bg.label("All Posts").classes("text-h3 q-mb-lg") # Post list for i in range(10): with bg.row().classes("bg-white rounded q-pa-lg q-mb-md shadow-1"): with bg.column().classes("col-12"): bg.label(f"Blog Post {i+1}").classes("text-h6 q-mb-sm") bg.label("Published on January 1, 2025").classes("text-caption text-grey-6 q-mb-md") bg.label("This is a preview of the blog post content...").classes("text-body2 q-mb-md") bg.link("Read Full Post", f"/post/{i+1}").classes("q-btn q-btn-outline") create_footer() # Individual Post Page with bg.page("/post/:id", "PostPage", "Blog Post"): create_header() with bg.column().classes("q-pa-xl max-width-md mx-auto"): bg.label("Blog Post Title").classes("text-h3 q-mb-md") bg.label("Published on January 1, 2025 by Author").classes("text-caption text-grey-6 q-mb-lg") bg.label("Blog post content goes here...").classes("text-body1 q-mb-lg") bg.label("More content and paragraphs...").classes("text-body1 q-mb-lg") with bg.row().classes("q-mt-xl"): bg.link("← Back to Posts", "/posts").classes("q-btn q-btn-outline") create_footer() # About Page with bg.page("/about", "AboutPage", "About"): create_header() with bg.column().classes("q-pa-xl max-width-md mx-auto text-center"): bg.label("About Me").classes("text-h3 q-mb-lg") bg.label("Welcome to my personal blog...").classes("text-body1 q-mb-lg") bg.label("I write about technology, life, and everything in between.").classes("text-body1 q-mb-lg") create_footer() # Contact Page with bg.page("/contact", "ContactPage", "Contact"): create_header() with bg.column().classes("q-pa-xl max-width-sm mx-auto"): bg.label("Contact Me").classes("text-h3 q-mb-lg text-center") # Contact form bg.input(placeholder="Your Name").classes("q-mb-md").props("filled required") bg.input(placeholder="Your Email").classes("q-mb-md").props("filled required type=email") bg.input(placeholder="Subject").classes("q-mb-md").props("filled required") bg.input(placeholder="Your Message").classes("q-mb-lg").props("filled required type=textarea rows=4") bg.button("Send Message").classes("q-btn q-btn-primary full-width") create_footer() # Build the application bg.build("blog-app") Route Configuration ------------------- Generated Router Files ~~~~~~~~~~~~~~~~~~~~~~~ BadGUI automatically generates Vue Router configuration files: **``src/router/routes.js``:** .. code-block:: javascript const routes = [ { path: '/', component: () => import('layouts/MainLayout.vue'), children: [ { path: '', component: () => import('pages/HomePage.vue') }, { path: '/about', component: () => import('pages/AboutPage.vue') }, { path: '/posts', component: () => import('pages/PostsPage.vue') }, { path: '/post/:id', component: () => import('pages/PostPage.vue') }, { path: '/contact', component: () => import('pages/ContactPage.vue') } ] } ] **``src/router/index.js``:** .. code-block:: javascript import { createRouter, createWebHistory } from 'vue-router' import routes from './routes' const router = createRouter({ history: createWebHistory(), routes }) export default router Page Components ~~~~~~~~~~~~~~~ Each page generates a corresponding Vue component: **``src/pages/HomePage.vue``:** .. code-block:: vue Best Practices -------------- URL Structure ~~~~~~~~~~~~~ 1. **Use clear, descriptive URLs**: ``/about``, ``/contact``, ``/blog/post-title`` 2. **Keep URLs short and readable**: Avoid deep nesting 3. **Use hyphens for multi-word URLs**: ``/user-profile`` not ``/userprofile`` 4. **Be consistent**: Choose a pattern and stick to it Page Organization ~~~~~~~~~~~~~~~~~ 1. **Group related pages**: Keep similar functionality together 2. **Use consistent layouts**: Share common elements like headers/footers 3. **Plan your navigation flow**: Make it easy for users to move between pages 4. **Consider SEO**: Use descriptive page titles Performance Considerations ~~~~~~~~~~~~~~~~~~~~~~~~~~ 1. **Code splitting**: Vue Router automatically splits pages into separate chunks 2. **Lazy loading**: Pages are loaded only when needed 3. **Minimize page complexity**: Keep individual pages focused and lightweight Error Handling -------------- 404 Error Page ~~~~~~~~~~~~~~ BadGUI automatically generates a 404 error page: .. code-block:: python # This is generated automatically with bg.page("/:catchAll(.*)*", "ErrorNotFound", "Page Not Found"): bg.label("Oops. Nothing here...").classes("text-h2") bg.link("Go Home", "/").classes("q-btn q-btn-primary") The generated project includes proper error handling for routes that don't exist. Advanced Routing ---------------- Route Guards ~~~~~~~~~~~~ While BadGUI generates static routes, you can add route guards in the generated Vue project: .. code-block:: javascript // In the generated router/index.js, you can add: router.beforeEach((to, from, next) => { // Add authentication, analytics, etc. next() }) Programmatic Navigation ~~~~~~~~~~~~~~~~~~~~~~~ In the generated Vue components, you can add programmatic navigation: .. code-block:: vue This allows for dynamic navigation based on user actions or application state.