๐Ÿฝ๏ธ

Recipe Universe

Professional Recipe Platform

โšก Blazor Superpowers

Experience the full power of Blazor Server - real-time interactivity, seamless C# throughout the stack, and modern web development without JavaScript complexity.

⚡ Interactive Server

Interactive Blazor Components

Real-time components with SignalR for instant server-client communication

๐Ÿ”„ Real-time Interactivity

Live Recipe Activity

Real-time updates across all connected users

Connected
1
Recipe Views Today
12
Users Online

๐Ÿ” Smart Recipe Search

Real-time search with instant results - no page refreshes needed!

Authentic Spaghetti Carbonara

The classic Roman pasta dish with eggs, cheese, pancetta, and black pepper. No cream needed!

โฑ๏ธ 20 min โญ 4.8 Italian

Creamy Butter Chicken

Tender marinated chicken in a rich, creamy tomato-based curry sauce with aromatic spices.

โฑ๏ธ 45 min โญ 4.7 Indian

Authentic Street Tacos

Tender seasoned beef in soft corn tortillas with fresh cilantro and onions.

โฑ๏ธ 25 min โญ 4.6 Mexican

Decadent Chocolate Cake

Rich, moist chocolate cake with creamy chocolate frosting.

โฑ๏ธ 35 min โญ 4.8 Dessert

Authentic Pad Thai

Classic Thai stir-fried noodles with tamarind, fish sauce, and fresh herbs.

โฑ๏ธ 15 min โญ 4.7 Asian

Classic American Burger

Juicy beef patty with all the fixings on a toasted bun - the perfect American classic.

โฑ๏ธ 15 min โญ 4.8 American

๐Ÿ’ป How Real-time Search Works

// InteractiveRecipeSearch.razor
@rendermode InteractiveServer
@inject RecipeService RecipeService
<div class="bg-white rounded-lg shadow-lg p-6">
<input @bind="searchTerm" @bind:event="oninput"
class="w-full px-4 py-3 border rounded-lg" />
@foreach (var recipe in filteredRecipes)
{
<div>@recipe.Name</div>
}
</div>
@code {
private string searchTerm = "";
private List<Recipe> allRecipes = new();
private List<Recipe> filteredRecipes = new();
// This property automatically triggers UI updates
private string SearchTerm
{
get => searchTerm;
set
{
searchTerm = value;
// Filter happens instantly on server
filteredRecipes = allRecipes
.Where(r => r.Name.Contains(value, StringComparison.OrdinalIgnoreCase))
.ToList();
// UI updates via SignalR automatically
StateHasChanged();
}
}
}
๐Ÿ”„ Real-time Binding

@bind:event="oninput" creates instant two-way data binding. Every keystroke triggers the setter.

โšก Server Processing

Filtering happens on the server with full C# power. Complex business logic stays secure.

๐Ÿ“ก SignalR Magic

StateHasChanged() sends only DOM differences over SignalR. Ultra-efficient updates.

Why This Matters

Real-time updates happen automatically through SignalR. Search filters instantly without page reloads. All with C# code - no JavaScript required!

๐Ÿ“ Powerful Forms & Validation

๐Ÿ“ Quick Recipe Builder

Blazor's powerful forms with real-time validation

โš ๏ธ Please fill required fields

๐Ÿ“ Advanced Form Validation in Action

๐Ÿ“‹ Model with Data Annotations
// Recipe.cs - Shared Model
public class Recipe
{
[Required(ErrorMessage = "Recipe name is required")]
[StringLength(100, MinimumLength = 3)]
public string Name { get; set; } = "";
[Required, Range(1, 300)]
public int CookingTime { get; set; }
[Required, MinLength(1)]
public List<Ingredient> Ingredients { get; set; } = new();
[Url(ErrorMessage = "Must be valid URL")]
public string? ImageUrl { get; set; }
}
๐ŸŽฏ Blazor Form Component
// RecipeFormDemo.razor
<EditForm Model="@newRecipe" OnValidSubmit="@HandleSubmit">
<DataAnnotationsValidator />
<ValidationSummary class="text-red-600" />
@ // Two-way binding with validation
<InputText @bind-Value="newRecipe.Name"
class="form-input" placeholder="Recipe name" />
<ValidationMessage For="@(() => newRecipe.Name)" />
<InputNumber @bind-Value="newRecipe.CookingTime"
class="form-input" />
<ValidationMessage For="@(() => newRecipe.CookingTime)" />
<button type="submit" disabled="@(!context.IsValid())">
Create Recipe
</button>
</EditForm>
@code {
private Recipe newRecipe = new();
private async Task HandleSubmit()
{
// Server-side processing with validation
await RecipeService.CreateAsync(newRecipe);
newRecipe = new(); // Reset form
}
}
๐Ÿ”„ Auto-Binding

@bind-Value creates two-way binding with automatic UI updates

โœ… Real-time Validation

ValidationMessage shows errors instantly as user types

๐Ÿ›ก๏ธ Type Safety

Strongly-typed expressions prevent runtime errors

๐ŸŽฏ Server Logic

Business rules enforced securely on server

Built-in Form Magic

Data annotations for validation, two-way binding, real-time validation feedback, and seamless model binding. No manual DOM manipulation needed!

๐ŸŽฏ Component State & Communication

๐ŸŽฏ Component State Management

Watch how Blazor components communicate and share state seamlessly

Recipe Counter

0
Recipes in Collection

Collection Progress

Progress to Goal 0/20
20 recipes to go
5 50

Real-time Activity Log

No activity yet - try the buttons above!
0
Total Actions
0
Recipes Added
0
Recipes Removed

๐ŸŽฏ Component Communication & State Management

๐Ÿ“ก Parent Component
// StateManagementDemo.razor
<div class="space-y-4">
@ // Parent manages shared state
<h4>Cart: @cartItems.Count items</h4>
<h5>Total: $@totalPrice.ToString("F2")</h5>
@ // Pass callbacks to children
<RecipeCard Recipe="@recipe"
OnAddToCart="@HandleAddToCart" />
<ShoppingCart Items="@cartItems"
OnRemove="@HandleRemove" />
</div>
@code {
private List<CartItem> cartItems = new();
private decimal totalPrice =>
cartItems.Sum(i => i.Price * i.Quantity);
private void HandleAddToCart(Recipe recipe)
{
// State change triggers re-render
cartItems.Add(new CartItem(recipe));
// All child components update automatically
}
}
๐Ÿท๏ธ Child Component
// RecipeCard.razor
<div class="recipe-card">
<h4>@Recipe.Name</h4>
<p>$@Recipe.Price</p>
<button @onclick="@HandleClick"
disabled="@isAdding">
@(isAdding ? "Adding..." : "Add to Cart")
</button>
</div>
@code {
// Parameters from parent
[Parameter] public Recipe Recipe { get; set; }
[Parameter] public EventCallback<Recipe>
OnAddToCart { get; set; }
private bool isAdding;
private async Task HandleClick()
{
isAdding = true;
// Notify parent of state change
await OnAddToCart.InvokeAsync(Recipe);
isAdding = false;
}
}
๐Ÿ›’ Service Layer
// CartService.cs
public class CartService
{
private List<CartItem> _items = new();
// Observable pattern for state changes
public event Action? OnCartChanged;
public IReadOnlyList<CartItem> Items => _items;
public void AddItem(Recipe recipe)
{
_items.Add(new CartItem(recipe));
// Notify all subscribers
OnCartChanged?.Invoke();
}
}
// In component:
@inject CartService Cart
@implements IDisposable
protected override void OnInitialized()
{
Cart.OnCartChanged += StateHasChanged;
}
public void Dispose()
{
Cart.OnCartChanged -= StateHasChanged;
}
๐Ÿ”„ State Flow Visualization
1. User Clicks Button
โ†’
2. EventCallback Fires
โ†’
3. Parent State Changes
โ†’
4. UI Re-renders Automatically

Key insight: Blazor's component model handles the complex state synchronization automatically. No manual DOM updates or state management libraries needed!

State That Just Works

Components automatically re-render when state changes. Share state between components effortlessly. Reactive UI updates with zero boilerplate!

โšก Performance & Architecture Benefits

Server-Side Rendering

Lightning-fast initial page loads with full HTML rendered on the server. SEO-friendly by default.

Type Safety

Full C# type safety from database to UI. Catch errors at compile time, not runtime.

Developer Experience

Use familiar C# debugging, IntelliSense, and tooling. Share models between client and server.

Component Architecture

Reusable components with clean separation of concerns. Compose complex UIs from simple parts.

Real-time by Default

SignalR integration means real-time features work out of the box. No complex WebSocket setup needed.

Security First

Server-side execution means sensitive logic stays secure. Built-in protection against XSS and other attacks.

๐Ÿ” Blazor vs Traditional Approaches

๐Ÿ’ป Real Code Comparison: Adding Interactive Search

โŒ Traditional (MVC + jQuery)
C# Controller
[HttpPost]
public JsonResult SearchRecipes(string term)
{
var results = _service.SearchRecipes(term);
return Json(results.Select(r => new
{
id = r.Id,
name = r.Name,
// Manual serialization required
}));
}
HTML Template
<input id="search" type="text" />
<div id="results">
<!-- Results go here -->
</div>
JavaScript (jQuery)
$('#search').on('input', function() {
const term = $(this).val();
$.post('/Recipe/SearchRecipes',
{ term: term }, function(data) {
let html = '';
data.forEach(recipe => {
html += `<div>${recipe.name}</div>`;
});
$('#results').html(html);
}).fail(function() {
// Error handling...
});
});
Problems:
  • โ€ข 3 different languages/files to maintain
  • โ€ข Manual DOM manipulation prone to XSS
  • โ€ข No compile-time type checking
  • โ€ข Complex error handling across boundaries
  • โ€ข Separate build processes for JS/CSS
โœ… Blazor Server
Single .razor File
@rendermode InteractiveServer
@inject RecipeService RecipeService
<input @bind="searchTerm" @bind:event="oninput"
class="w-full px-4 py-3 border rounded" />
<div class="space-y-2">
@foreach (var recipe in filteredRecipes)
{
<div class="p-3 border rounded">
<h4>@recipe.Name</h4>
<p>@recipe.Description</p>
</div>
}
</div>
@code {
private string searchTerm = "";
private List<Recipe> allRecipes = new();
private List<Recipe> filteredRecipes = new();
protected override async Task OnInitializedAsync()
{
allRecipes = await RecipeService.GetAllAsync();
filteredRecipes = allRecipes;
}
private string SearchTerm
{
get => searchTerm;
set
{
searchTerm = value;
// Type-safe filtering
filteredRecipes = allRecipes
.Where(r => r.Name.Contains(value,
StringComparison.OrdinalIgnoreCase))
.ToList();
}
}
}
Benefits:
  • โ€ข Single file, single language (C#)
  • โ€ข Automatic XSS protection via Razor
  • โ€ข Full IntelliSense and type safety
  • โ€ข Built-in error handling and debugging
  • โ€ข No JavaScript build process needed

โŒ Traditional Approach

๐Ÿคน Context switching between C# backend and JavaScript frontend
๐Ÿ› Runtime errors from type mismatches between server/client
๐Ÿ”„ Manual DOM manipulation and state synchronization
๐Ÿ“ฆ Multiple build processes and toolchains
๐ŸŽญ Duplicated validation logic on client and server

โœ… Blazor Approach

๐ŸŽฏ Single language (C#) for entire application stack
๐Ÿ›ก๏ธ Compile-time type safety from database to UI
โšก Automatic state management and UI updates
๐Ÿ”ง Single build process with familiar .NET tooling
๐Ÿ”„ Shared models and validation logic everywhere

๐Ÿ“Š Development Productivity Comparison

75%
Less Code to Write
Single file vs multiple
90%
Fewer Runtime Errors
Compile-time checking
60%
Faster Development
No context switching
50%
Easier Debugging
Single debug session

Ready to Experience Blazor?

This entire application is built with Blazor Server - no JavaScript frameworks needed!

An error has occurred. This application may no longer respond until reloaded. Reload ๐Ÿ—™