Transition from Modal to Full Page
In our recipe finder application, the initial approach involved displaying recipe details within a <v-dialog> modal. This setup housed various elements such as ingredients, nutritional information, videos, AI chef features, and more. However, managing this within HomePage.vue resulted in a bloated 'god component,' handling everything from search forms to modals.
Challenges with Modals
The use of modals presented several issues:
- URL Limitations: Since the URL didn't change, sharing specific recipe links or indexing by search engines was impossible.
- Back Button Ineffectiveness: Users couldn't utilize the back button effectively, affecting navigation.
Introducing a Dedicated Route
To address these challenges, we established a dedicated /recipe/:slug route, transferring the recipe detail logic to RecipeDetailPage.vue.
// router/index.ts
{
path: '/recipe/:slug',
component: () => import('@/pages/RecipeDetailPage.vue'),
meta: { title: 'Recipe' }
}
This change enabled human-readable, stable slugs derived from recipe IDs and titles, enhancing both user experience and SEO.
Streamlining HomePage.vue
With the new page in place, we streamlined HomePage.vue by removing modal-related elements:
isRecipeModalOpenreferencesselectedRecipeDetailsandloadingRecipeDetails- Modal handlers and imports
This refactoring reduced the script size significantly, allowing HomePage.vue to focus solely on search functionality.
New Page Layout
The redesigned page layout employs a Vuetify two-column grid:
- Main Content: Positioned on the left, displaying images, titles, and recipe details.
- Sidebar: Sticky and collapsible, featuring tools like the AI Chef and nutrition snapshot.
<v-row>
<v-col cols="12" lg="8">
<v-img :src="recipe.image" cover rounded="lg" class="mb-6" />
<h1 class="recipe-title">{{ recipe.title }}</h1>
</v-col>
<v-col cols="12" lg="4" class="d-none d-lg-flex flex-column">
<div class="sidebar-sticky">
<!-- Sidebar content -->
</div>
</v-col>
</v-row>
Mobile Optimization
On mobile, action buttons become icon-only, and the AI Chef feature is accessed via a bottom sheet, ensuring a clutter-free interface.
Enhancing SEO and Performance
With each recipe now having a unique URL, we dynamically inject meta tags to improve SEO:
const injectMetaTags = (title, summary, imageUrl) => {
document.title = `${title} | Recipe Finder`;
// Set meta tags for Open Graph and Twitter
};
Additionally, lazy loading is utilized for non-critical components, ensuring faster initial page loads.
Addressing Auth Issues
We resolved an authentication issue by verifying user login status before interacting with certain features, enhancing user experience.
Conclusion
This transformation from modal to full-page views has resulted in a cleaner codebase, improved SEO, and a more user-friendly application. The app now supports better navigation and sharing capabilities, aligning with modern web standards.