### Configure Bolero Remoting Client Startup Source: https://github.com/fsbolero/bolero/wiki/Remoting Configures the Blazor application startup to support Bolero Remoting. This involves adding the remoting services to the dependency injection container using `AddRemoting()`. This setup is essential for enabling client-side access to remote services. ```fsharp open Bolero.Remoting type Startup() = member __.ConfigureServices(services: IServiceCollection) = services.AddRemoting() |> ignore ``` -------------------------------- ### Client-side Usage of Remote Service in Elmish (F#) Source: https://context7.com/fsbolero/bolero/llms.txt This example shows how to consume the `IBookService` from the client-side using the Elmish architecture within a Blazor component. It defines the component's model, messages, and update logic, demonstrating how to trigger remote calls and handle responses asynchronously. It uses `Cmd.OfAsync.either` for handling success and error cases. ```fsharp // Client-side usage in Elmish type Model = { books: Book list loading: bool error: string option } type Msg = | LoadBooks | BooksLoaded of Book list | AddBook of Book | BookAdded of int | Error of exn let update (remote: IBookService) msg model = match msg with | LoadBooks -> { model with loading = true }, Cmd.OfAsync.either remote.getBooks () BooksLoaded Error | BooksLoaded books -> { model with books = books; loading = false }, Cmd.none | AddBook book -> model, Cmd.OfAsync.either remote.addBook book BookAdded Error | BookAdded id -> model, Cmd.ofMsg LoadBooks | Error e -> { model with error = Some e.Message; loading = false }, Cmd.none // Component with remote service type BookListComponent() = inherit ProgramComponent() override this.Program = let remote = this.Remote() Program.mkProgram (fun _ -> { books = []; loading = false; error = None }, Cmd.ofMsg LoadBooks) (update remote) view ``` -------------------------------- ### Implement Bolero Remoting Service on Server Source: https://github.com/fsbolero/bolero/wiki/Remoting Provides a basic implementation of a remote service on the server-side using a global mutable map for storage. It includes functions for getting, setting, and deleting entries. The service is registered with `AddRemoting` and activated using `UseRemoting` middleware in the ASP.NET Core startup. ```fsharp // A simple global map as storage. // A real-world app would probably use a database instead. let mutable storage = Map.empty let myService = { getEntry = fun key -> async { return Map.tryFind key } setEntry = fun (key, value) -> async { storage <- Map.add key value storage } deleteEntry = fun key -> async { storage <- Map.remove key storage } } type Startup() = member this.ConfigureServices(services: IServiceCollection) = services.AddRemoting(myService) |> ignore member this.Configure(app: IApplicationBuilder) = app.UseRemoting() .UseBlazor() |> ignore ``` -------------------------------- ### Create NavLink Component Source: https://github.com/fsbolero/bolero/wiki/HTML Provides an example of using the `navLink` helper function to create Blazor `NavLink` components. These links dynamically apply an 'active' CSS class based on the current URL matching the `href` and specified match type (`NavLinkMatch.All` or `NavLinkMatch.Prefix`). ```fsharp let myMenu = ul [] [ li [] [navLink NavLinkMatch.All [attr.href "/"] [text "Home"]] li [] [navLink NavLinkMatch.Prefix [attr.href "/blog"] [text "Blog"]] ] ``` -------------------------------- ### F# Elmish Program Integration in Bolero Source: https://context7.com/fsbolero/bolero/llms.txt Demonstrates how to build F# web applications using the Elmish architecture within Bolero. It covers defining the Model, Messages, and Update functions, as well as creating the View. Components inherit from `ProgramComponent` and integrate with Bolero's router. This snippet also shows an example of handling asynchronous commands. ```fsharp open Elmish open Bolero open Bolero.Html // Define the model type Model = { counter: int input: string items: string list } // Define messages type Msg = | Increment | Decrement | SetInput of string | AddItem | RemoveItem of int // Initialize the model let init () = { counter = 0; input = ""; items = [] }, Cmd.none // Update function let update msg model = match msg with | Increment -> { model with counter = model.counter + 1 }, Cmd.none | Decrement -> { model with counter = model.counter - 1 }, Cmd.none | SetInput text -> { model with input = text }, Cmd.none | AddItem -> { model with items = model.input :: model.items; input = "" }, Cmd.none | RemoveItem idx -> { model with items = List.removeAt idx model.items }, Cmd.none // View function let view model dispatch = div { h1 { $"Counter: {model.counter}" } button { on.click (fun _ -> dispatch Increment); "+" } button { on.click (fun _ -> dispatch Decrement); "-" } input { attr.value model.input on.input (fun e -> dispatch (SetInput (e.Value :?> string))) } button { on.click (fun _ -> dispatch AddItem); "Add Item" } ul { forEach (List.indexed model.items) <| fun (idx, item) -> li { text item button { on.click (fun _ -> dispatch (RemoveItem idx)); "Remove" } } } } // Create the component type MyApp() = inherit ProgramComponent() override this.Program = Program.mkProgram (fun _ -> init()) update view |> Program.withRouter (Router.infer SetPage (fun m -> m.currentPage)) // With async commands let loadData id = async { do! Async.Sleep 1000 return { id = id; name = "Sample" } // Assuming a record type with 'id' and 'name' } // Example update function handling async command type AppModel = { user: User option } // Assuming a User type type AppMsg = LoadUser of int | UserLoaded of User let updateWithAsync msg model = // model here is of type AppModel match msg with | LoadUser id -> model, Cmd.OfAsync.perform loadData id UserLoaded | UserLoaded user -> { model with user = Some user }, Cmd.none ``` -------------------------------- ### Recursive Type Routing with EndPoint Attributes Source: https://github.com/fsbolero/bolero/wiki/Routing Demonstrates the use of `EndPoint` attributes with recursive F# types to define complex routing structures. This example shows how nested types and path parameters can be combined to create intricate URL patterns. ```fsharp type Page = | [ Article of ArticleId] // -> /article/123/announcing-bolero | [ List of tags: list] // -> /list/bolero/blazor | [ LoginAndRedirectTo of page: Page] // -> /login/list/bolero/blazor and ArticleId = { uid: int slug: string } ``` -------------------------------- ### Bolero Template with Node Holes Source: https://github.com/fsbolero/bolero/wiki/Templating Illustrates the use of Node holes within an HTML template for inserting dynamic content. These holes can be filled with either strings or F# Nodes. The example shows filling a 'Who' hole with a string and then with a Node. ```fsharp type Hello = Template<"hello.html"> // Fill with a string let hello = Hello().Who("world").Elt() // Fill with a Node let hello = Hello().Who(b [] [text "world"]).Elt() ``` -------------------------------- ### Bolero Template with Combined Node and Attribute Holes Source: https://github.com/fsbolero/bolero/wiki/Templating Shows an example where a hole is used in both an HTML attribute and node content. The type provider ensures that such a hole can still only be filled by a string, simplifying dynamic content updates for both presentation and behavior. ```fsharp type Hello = Template<"hello.html"> let hello = Hello().Label("First name").Elt() ``` -------------------------------- ### Bolero Reusing Data Binding Holes Source: https://github.com/fsbolero/bolero/wiki/Templating Shows how the same binding hole (e.g., `${Name}`) can be used across multiple elements, ensuring data consistency. Changes in one bound element are reflected in others. This example binds an input field and a paragraph displaying the same name. ```html

Hello, ${Name}!

``` ```fsharp type Model = { name: string } type Message = | SetName of string type Hello = Template<"hello.html"> let hello model dispatch = Hello() .Name(model.name, fun n -> dispatch (SetName n)) .Elt() ``` -------------------------------- ### Bolero Template with Event Holes Source: https://github.com/fsbolero/bolero/wiki/Templating Demonstrates how to handle event attributes in Bolero templates using event holes. These holes are filled with anonymous functions that accept a `UIEventArgs` (or a more specific subtype) and return `unit`. The example shows a basic click handler. ```fsharp type Hello = Template<"hello.html"> let hello = Hello().Greet(fun _ -> printfn "Hello, world!").Elt() ``` -------------------------------- ### Bolero `bind-onchange` Event Handler Source: https://github.com/fsbolero/bolero/wiki/Templating Illustrates overriding the default event handler for data binding by explicitly using `bind-onchange`. This handler triggers updates only when the change is committed (e.g., pressing Enter or unfocusing), unlike `oninput`. The example binds an input to the `Name` hole. ```html

Hello, ${Name}!

``` ```fsharp type Model = { name: string } type Message = | SetName of string type Hello = Template<"hello.html"> let hello model dispatch = Hello() .Name(model.name, fun n -> dispatch (SetName n)) .Elt() ``` -------------------------------- ### Conditional Rendering with Bolero.Html `cond` Source: https://github.com/fsbolero/bolero/wiki/HTML Explains and demonstrates the use of the `cond` function for handling conditional elements and attributes in Bolero. This is crucial for avoiding runtime errors in Blazor by ensuring consistent DOM structure. Examples cover boolean conditions and F# union types like `option<'T>`. ```fsharp let myButton (label: option) = button [] [ cond label.IsSome <| function | true -> text label.Value | false -> empty ] ``` ```fsharp let myButton (label: option) = button [] [ cond label <| function | Some l -> text l | None -> empty ] ``` ```fsharp /// A list of usernames, truncated to two + number of others type UserList = | One of string | Two of string * string | Many of string * string * int /// Shows one of the following, depending on the number of users: /// * "*Alice* likes this" /// * "*Alice* and *Bob* like this" /// * "*Alice*, *Bob* and 12 others like this" let showLikes (users: UserList) = concat [ cond users <| function | One uname -> b [] [text uname] | Two (uname1, uname2) -> concat [ b [] [text uname1] text " and " b [] [text uname2] ] | Many (uname1, uname2, others) -> concat [ b [] [text uname1] text ", " b [] [text uname2] textf " and %i others" others ] cond users <| function | One _ -> text " likes this." | _ -> text " like this." ] ``` -------------------------------- ### Bolero Template with Attribute Holes Source: https://github.com/fsbolero/bolero/wiki/Templating Explains how to use attribute holes in Bolero HTML templates. These holes are defined within HTML attributes and can only be filled with string values. The example demonstrates filling a 'Class' attribute. ```fsharp type Hello = Template<"hello.html"> let hello = Hello().Class("heading").Elt() ``` -------------------------------- ### Instantiate a Blazor Component Source: https://github.com/fsbolero/bolero/wiki/HTML Illustrates how to create an instance of a Blazor component using the `comp` function. It shows how to pass attributes (like parameters) and child nodes when creating the component instance. ```fsharp let myElement = comp ["Who" => "world"] [] ``` -------------------------------- ### Create a Basic Blazor Component Source: https://github.com/fsbolero/bolero/wiki/HTML Demonstrates how to define a simple Blazor component by inheriting from the `Component` base class and overriding the `Render` method. This component renders a 'Hello, world!' message. ```fsharp type MyComponent() = inherit Component() override this.Render() = div [] [text "Hello, world!"] ``` -------------------------------- ### Register Remote Service in Startup (F#) Source: https://github.com/fsbolero/bolero/wiki/Remoting Register a remote service handler in your ASP.NET Core application's startup class using `AddRemoting`. This method registers the service by its type, enabling dependency injection. ```fsharp type Startup() = member this.ConfigureServices(services: IServiceCollection) = services.AddRemoting() |> ignore ``` -------------------------------- ### Instantiate Blazor NavLink Component in Bolero Source: https://context7.com/fsbolero/bolero/llms.txt Demonstrates how to use the `comp` builder to instantiate a Blazor `NavLink` component within Bolero. It shows how to set properties like `Match` and `href`, and apply CSS classes. ```fsharp open Bolero.Html open Microsoft.AspNetCore.Components open Microsoft.AspNetCore.Components.Routing // Using Blazor NavLink component let navigationLink url text = comp { "Match" => NavLinkMatch.All attr.href url attr.``class`` "nav-link" text } ``` -------------------------------- ### Define and Implement Remote Service Interface (F#) Source: https://context7.com/fsbolero/bolero/llms.txt This snippet demonstrates defining a remote service interface (`IBookService`) using an F# record of async functions and its server-side implementation (`BookService`) using `RemoteHandler`. It includes basic CRUD operations for books. The `BasePath` property specifies the service's endpoint. ```fsharp open Bolero.Remoting // Define the remote service interface type IBookService = { getBooks: unit -> Async getBook: int -> Async addBook: Book -> Async updateBook: Book -> Async deleteBook: int -> Async searchBooks: string -> Async } interface IRemoteService with member _.BasePath = "/api/books" // Server-side implementation type BookService(db: IDatabase) = inherit RemoteHandler() override _.Handler = { getBooks = fun () -> async { return! db.GetAllBooks() } getBook = fun id -> async { return! db.GetBookById(id) } addBook = fun book -> async { return! db.InsertBook(book) } updateBook = fun book -> async { do! db.UpdateBook(book) } deleteBook = fun id -> async { do! db.DeleteBook(id) } searchBooks = fun query -> async { return! db.SearchBooks(query) } } ``` -------------------------------- ### Server-Side Service Implementation and Registration Source: https://github.com/fsbolero/bolero/wiki/Remoting Details how to implement a remote service on the server-side and register it with ASP.NET Core. ```APIDOC ## Server-Side Service Implementation and Registration ### Description Provides instructions for implementing a remote service on the server, including a simple in-memory storage example, and how to register this service and the remoting middleware in the ASP.NET Core startup configuration. ### Method N/A (Server-side configuration and implementation) ### Endpoint N/A (Server-side configuration and implementation) ### Parameters N/A ### Request Example ```fsharp // Service Implementation: let mutable storage = Map.empty let myService = { getEntry = fun key -> async { return Map.tryFind key } setEntry = fun (key, value) -> async { storage <- Map.add key value storage } deleteEntry = fun key -> async { storage <- Map.remove key storage } } // In ASP.NET Core Startup.ConfigureServices: type Startup() = member this.ConfigureServices(services: IServiceCollection) = services.AddRemoting(myService) |> ignore // In ASP.NET Core Startup.Configure: type Startup() = member this.Configure(app: IApplicationBuilder) = app.UseRemoting() .UseBlazor() |> ignore ``` ### Response N/A (Server-side configuration and implementation) ``` -------------------------------- ### Instantiate Input ElmishComponent using ecomp Source: https://github.com/fsbolero/bolero/wiki/Elmish This F# code demonstrates how to use the `ecomp` function to instantiate the `Input` ElmishComponent within a parent view. It shows how to pass the relevant sub-model and a dispatch function to the `ecomp` helper, integrating the optimized sub-component into the main UI. ```fsharp let view model dispatch = div [] [ ecomp model.firstName (fun n -> dispatch (SetFirstName n)) ecomp model.lastName (fun n -> dispatch (SetLastName n)) text (sprintf "Hello, %s %s!" model.firstName model.lastName) ] ``` -------------------------------- ### Call Bolero Remoting Service from Client Update Source: https://github.com/fsbolero/bolero/wiki/Remoting Demonstrates how to call a Bolero Remoting service from the client-side `update` function within an Elmish application. It shows how to retrieve the service using `this.Remote()`, construct asynchronous commands using `Cmd.ofAsync`, and handle responses or errors by dispatching messages. ```fsharp type Model = { latestRetrievedEntry : string * string } type Message = // Trigger a `getEntry` request | GetEntry of key: string // Received response of a `getEntry` request | GotEntry of key: string * value: string // A request threw an error | Error of exn let update myService message model = match message with | GetEntry key -> model, Cmd.ofAsync myService.getEntry key // async call and argument (fun value -> GotEntry(key, value)) // message to dispatch on response Error // message to dispatch on error | GotEntry(key, value) -> { model with latestRetrievedEntry = (key, value) }, [] | Error exn -> model, [] // In your Blazor startup, add support for remoting: type Startup() = inherit ProgramComponent() override this.Program = // Retrieve the service let myService = this.Remote() // Pass it to `update` Program.mkProgram (fun _ -> initModel, []) (update myService) view ``` -------------------------------- ### Create and Attach Inferred Router Source: https://github.com/fsbolero/bolero/wiki/Routing Demonstrates how to create an inferred router using `Router.infer` and attach it to a Bolero Elmish program. ```fsharp let router = Router.infer SetPage (fun m -> m.page) Program.mkSimple initModel update view |> Program.withRouter router ``` -------------------------------- ### Generic Blazor Component Instantiation in Bolero Source: https://context7.com/fsbolero/bolero/llms.txt Shows how to instantiate a generic Blazor component in Bolero using the `comp` builder. This approach allows for dynamic component instantiation based on a type parameter `T` that must implement `IComponent`. ```fsharp // Generic component usage let genericComponent<'T when 'T :> IComponent> = comp<'T> { "Param1" => "value1" "Param2" => 42 } ``` -------------------------------- ### Component Usage with Custom Update Check (F#) Source: https://github.com/fsbolero/bolero/wiki/Elmish Demonstrates how to use the `Input` component within a larger view. It shows instantiating `Input` components for first and last names, passing the model data and dispatch functions, and utilizing the custom `ShouldRender` logic for efficient updates. ```fsharp let view model dispatch = div [] [ ecomp { label = "First name: " value = model.firstName } (fun n -> dispatch (SetFirstName n)) ecomp { label = "Last name: " value = model.lastName } (fun n -> dispatch (SetLastName n)) text (sprintf "Hello, %s %s!" model.firstName model.lastName) ] ``` -------------------------------- ### Client-Side Service Retrieval and Usage Source: https://github.com/fsbolero/bolero/wiki/Remoting Demonstrates how to retrieve and use a remote service on the client-side within an Elmish application's `update` function. ```APIDOC ## Client-Side Service Usage ### Description Shows how to configure the Blazor application to use remoting, retrieve the client-side service instance, and invoke its methods within the Elmish `update` function using `Cmd.ofAsync`. ### Method N/A (Client-side logic) ### Endpoint N/A (Client-side logic) ### Parameters N/A ### Request Example ```fsharp // In Blazor startup: // services.AddRemoting() // In ProgramComponent: let myService = this.Remote() // In update function: type Model = { latestRetrievedEntry : string * string } type Message = | GetEntry of key: string | GotEntry of key: string * value: string | Error of exn let update myService message model = match message with | GetEntry key -> model, Cmd.ofAsync myService.getEntry key // async call and argument (fun value -> GotEntry(key, value)) // message to dispatch on response Error // message to dispatch on error | GotEntry(key, value) -> { model with latestRetrievedEntry = (key, value) }, [] | Error exn -> model, [] ``` ### Response N/A (Client-side logic) ``` -------------------------------- ### Render Collections with forEach in F# Source: https://github.com/fsbolero/bolero/wiki/HTML Demonstrates how to correctly render collections of items using the `forEach` function in F#. This avoids potential runtime errors that can occur with `List.map` for rendering lists of nodes. ```fsharp let listUsers (names: string list) = p [] [ text "Here are the users:" ul [] [ forEach names <| fun name -> li [] [text name] ] ] ``` -------------------------------- ### Define and Use a Custom Blazor Counter Component in Bolero Source: https://context7.com/fsbolero/bolero/llms.txt Illustrates defining a custom Blazor `Component` with parameters (`InitialCount`, `OnCountChanged`) and then integrating it into a Bolero view using the `comp` builder. It shows how to pass parameter values and event callbacks. ```fsharp // Custom Blazor component type CounterComponent() = inherit Component() [] member val InitialCount = 0 with get, set [] member val OnCountChanged = EventCallback() with get, set // Using the custom component in Bolero let counterView model dispatch = comp { "InitialCount" => model.counter "OnCountChanged" => EventCallback.Factory.Create( this, Action(fun count -> dispatch (CountChanged count)) ) } ``` -------------------------------- ### Lazy Blazor Component Rendering in Bolero Source: https://context7.com/fsbolero/bolero/llms.txt Explains how to implement lazy component rendering in Bolero for performance optimization using `lazyComp`. It shows a basic lazy component and how to create a lazy component with custom equality comparison using `lazyCompBy`. ```fsharp // Lazy components for performance let lazyView model = lazyComp (fun (m: Model) -> div { // This only re-renders when model changes expensiveRenderFunction m } ) model // Lazy with custom equality let lazyViewWithEquality model = lazyCompBy (fun m -> m.id) viewFunction model ``` -------------------------------- ### F# HTML Generation with Bolero DSL Source: https://context7.com/fsbolero/bolero/llms.txt Demonstrates creating HTML elements using Bolero's computation expression DSL. It covers basic element creation, attributes, nested content, text interpolation, lists with `forEach`, and conditional rendering with `cond`. This method compiles to efficient Blazor render tree operations. ```fsharp open Bolero.Html // Basic element creation let helloWorld = div { attr.``class`` "greeting" attr.id "main-greeting" h1 { "Hello, World!" } p { "Welcome to Bolero" } } // Element with attributes and nested content let userCard username email = div { attr.``class`` "user-card" h2 { $"User: {username}" } p { attr.``class`` "email" text $"Email: {email}" } button { attr.``class`` "btn btn-primary" on.click (fun _ -> printfn "Clicked!") "View Profile" } } // Using text interpolation let counter count = div { span { $"Count: {count}" } button { "Increment" } } // Lists with forEach let itemList items = ul { forEach items <| fun item -> li { attr.key item.id text item.name } } // Conditional rendering with cond let loginStatus isLoggedIn username = div { cond isLoggedIn <| function | true -> span { $"Welcome back, {username}!" } | false -> a { attr.href "/login"; "Login" } } ``` -------------------------------- ### Configure Hot Reload Server-Side Pipeline (F#) Source: https://github.com/fsbolero/bolero/wiki/Templating Enables the hot reload middleware in the server-side application's request pipeline. This is done using the UseHotReload extension method, usually placed before UseBlazor. ```fsharp member this.Configure(app: IApplicationBuilder, env: IHostingEnvironment) = app #if DEBUG .UseHotReload() #endif .UseBlazor() |> ignore ``` -------------------------------- ### Create HTML Elements with Bolero.Html Source: https://github.com/fsbolero/bolero/wiki/HTML Demonstrates creating standard HTML elements like div, h1, and p using Bolero's F# functions. It shows how to pass attributes and child elements, including text nodes created with `text` and `textf`. Elements that cannot have children, like `br`, are also handled. ```fsharp let myElement name = div [] [ h1 [] [text "My app"] p [] [textf "Hello %s and welcome to my app!" name] ] ``` ```fsharp let myElement = p [] [ text "First line of the paragraph." br [] text "Second line of the paragraph." ] ``` -------------------------------- ### F# Event Handling and Data Binding in Bolero Source: https://context7.com/fsbolero/bolero/llms.txt Illustrates handling user interactions and data binding in Bolero using type-safe event callbacks. It covers click handlers, input events, asynchronous operations, two-way binding for text, checkboxes, numeric inputs, and keyboard events. ```fsharp open Bolero.Html open Microsoft.AspNetCore.Components.Web // Click handlers let clickExample dispatch = button { on.click (fun (e: MouseEventArgs) -> dispatch ButtonClicked ) "Click Me" } // Input handling let textInput value dispatch = input { attr.value value on.input (fun e -> let newValue = e.Value :?> string dispatch (TextChanged newValue) ) } // Async event handlers let asyncButton dispatch = button { on.async.click (fun _ -> async { do! Async.Sleep 1000 dispatch DataLoaded }) "Load Data" } // Two-way binding for inputs let boundInput model dispatch = input { bind.input.string model.text (fun v -> dispatch (SetText v)) } // Checkbox binding let checkbox isChecked dispatch = input { attr.``type`` "checkbox" bind.``checked`` isChecked (fun v -> dispatch (SetChecked v)) } // Numeric input binding let numberInput value dispatch = input { attr.``type`` "number" bind.input.int value (fun v -> dispatch (SetNumber v)) } // Keyboard event handling let keyboardInput dispatch = input { on.keydown (fun (e: KeyboardEventArgs) -> if e.Key = "Enter" then dispatch SubmitForm ) } ``` -------------------------------- ### Configure Hot Reload Server-Side Services (F#) Source: https://github.com/fsbolero/bolero/wiki/Templating Configures the application services to enable hot reloading on the server-side. It uses the AddHotReload extension method, specifying the directory containing HTML files. This configuration is typically conditional on DEBUG builds. ```fsharp member this.ConfigureServices(services: IServiceCollection) = services #if DEBUG .AddHotReload(templateDir = "../MyClient/wwwroot") #endif |> ignore ``` -------------------------------- ### Generate Navigation Links with Router Utilities Source: https://github.com/fsbolero/bolero/wiki/Routing Shows how to use `router.Link` and `router.HRef` to generate navigation URLs for different endpoints within the application. ```fsharp a [attr.href (router.Link Home)] [text "Go to Home"] a [router.HRef Home] [text "Go to Home"] ``` -------------------------------- ### Create Custom HTML Elements with Bolero.Html Source: https://github.com/fsbolero/bolero/wiki/HTML Shows how to create custom HTML elements using the `elt` function when a specific function for that element is not provided by Bolero. This is useful for elements with data attributes or custom tags. ```fsharp let myElement = elt "data-paragraph" [] [ text "This is in a element." ] ``` -------------------------------- ### Add Bolero.HotReload.Server NuGet Package (F#) Source: https://github.com/fsbolero/bolero/wiki/Templating Adds the Bolero.HotReload.Server NuGet package to an F# project using the paket package manager. This is a server-side dependency for enabling hot reloading. ```fsharp paket add Bolero.HotReload.Server -p src/MyServer/MyServer.fsproj ``` -------------------------------- ### Implement Authorized Remote Service (F#) Source: https://context7.com/fsbolero/bolero/llms.txt This snippet illustrates how to implement authorization for remote service methods using Bolero Remoting. The `IAdminService` interface defines methods that require specific permissions. The `this.Authorize` method is used within the server-side implementation (`AdminService`) to enforce authorization checks before executing the actual logic. ```fsharp // Authorization in remoting type IAdminService = { deleteUser: int -> Async resetPassword: int -> Async } type AdminService(ctx: IHttpContextAccessor) = inherit RemoteHandler() override _.Handler = { deleteUser = this.Authorize <| fun id -> async { // Only admins can delete users do! deleteUserFromDb id } resetPassword = this.Authorize <| fun id -> async { return! generateNewPassword id } } ``` -------------------------------- ### Bolero Multiple Bindings with Different Event Handlers Source: https://github.com/fsbolero/bolero/wiki/Templating Demonstrates using the same data binding hole (`${Name}`) with different event handlers (`bind` for `oninput` and `bind-onchange`) on separate input elements. This allows for immediate updates on one input while deferring updates on another until the change is committed. ```html

When you type here, the second input's content is updated immediately:

When you type here, the first input's content is only updated when you exit the input box or press Enter:

``` -------------------------------- ### F# Router Configuration with Discriminated Unions in Bolero Source: https://context7.com/fsbolero/bolero/llms.txt Defines type-safe routes for a Bolero application using F# discriminated unions. It supports route parameters, query strings, and nested routes. The router automatically infers routes from the union cases and can be configured with a fallback for 'not-found' pages. It also shows how to generate navigation links programmatically. ```fsharp open Bolero // Define application routes type Page = | [] Home | [] About | [] UserProfile of id: int | [] BlogPost of slug: string | [] Search of query: string | [] EditArticle of id: int | [] Settings of section: string | [] NotFound // Router setup in Elmish type Model = { currentPage: Page } type Msg = | SetPage of Page let router = Router.infer SetPage (fun m -> m.currentPage) // Router with fallback for 404 let routerWithNotFound = Router.infer SetPage (fun m -> m.currentPage) |> Router.withNotFound NotFound // Generate links programmatically let navigation router = nav { a { attr.href (router.Link Home); "Home" } a { attr.href (router.Link About); "About" } a { attr.href (router.Link (UserProfile 42)); "User 42" } a { attr.href (router.Link (BlogPost "hello-world")); "Blog" } } // Complex routes with nested unions type InnerPage = | [] Overview | [] Settings | [] Profile type MainPage = | [] Home | [] Dashboard of InnerPage | [] Admin of section: string * InnerPage // Pattern matching on current page let view model dispatch = match model.currentPage with | Home -> homeView | About -> aboutView | UserProfile id -> userProfileView id | BlogPost slug -> blogPostView slug | NotFound -> notFoundView ``` -------------------------------- ### F# Union Types for Path Routing Source: https://github.com/fsbolero/bolero/wiki/Routing Demonstrates how F# union types can be mapped to URL paths. Each case in the union corresponds to a path segment, and its arguments form subsequent fragments. This allows for a declarative way to define routes. ```fsharp type Page = | Home // -> /Home | BlogArticle of id: int // -> /BlogEntry/42 | BlogList of user: string * page: int // -> /BlogList/tarmil/1 ``` -------------------------------- ### Define Input Component Model and Base Class (F#) Source: https://github.com/fsbolero/bolero/wiki/Elmish Defines the `InputModel` record to hold both label and value, and initializes an `Input` component inheriting from `ElmishComponent`. This sets up the basic structure for a customizable input field. ```fsharp type InputModel = { label: string; value: string } type Input() = inherit ElmishComponent() ``` -------------------------------- ### Wrap Elmish Program in Bolero ProgramComponent Source: https://github.com/fsbolero/bolero/wiki/Elmish This F# code shows how to create a Blazor component in Bolero by inheriting from `ProgramComponent` and assigning an Elmish program to its `Program` property. This integrates the Elmish application logic into the Blazor component lifecycle. ```fsharp open Elmish open Bolero type MyApp() = inherit ProgramComponent() override this.Program = program ``` -------------------------------- ### Implement Remote Handler with DI (F#) Source: https://github.com/fsbolero/bolero/wiki/Remoting Implement a remote service handler by inheriting from `RemoteHandler`. Dependencies like `ILogger` can be injected via the constructor. The `Handler` property defines the remote service's operations. ```fsharp type MyServiceHandler(log: ILogger) = inherit RemoteHandler() let mutable storage = Map.empty override this.Handler = { getEntry = fun key -> async { log.LogInformation("Retrieving {0}", key) return Map.tryFind key } setEntry = fun (key, value) -> async { log.LogInformation("Setting {0} to {1}", key, value) storage <- Map.add key value storage } deleteEntry = fun key -> async { log.LogInformation("Deleting {0}", key) storage <- Map.remove key storage } } ``` -------------------------------- ### Add Event Handlers in F# Source: https://github.com/fsbolero/bolero/wiki/HTML Illustrates how to add event handlers to elements in F# using the `on` submodule. It covers standard events like `click` and custom events using `on.event`, including access to event arguments. ```fsharp let myElement = button [on.click (fun _ -> printfn "Clicked!")] [ text "Click me!" ] ``` ```fsharp let myElement = button [ on.click (fun e -> printfn "Clicked at (%i, %i)" e.ClientX e.ClientY) ] [ text "Click me!" ] ``` ```fsharp let myElement = button [ on.event "customevent" (fun _ -> printfn "Custom event!") ] [ text "Click me!" ] ``` -------------------------------- ### Add Bolero.HotReload NuGet Package (F#) Source: https://github.com/fsbolero/bolero/wiki/Templating Adds the Bolero.HotReload NuGet package to an F# client project using the paket package manager. This is the client-side dependency for hot reloading. ```fsharp paket add Bolero.HotReload -p src/MyClient/MyClient.fsproj ``` -------------------------------- ### Configure Hot Reload Client-Side Elmish Program (F#) Source: https://github.com/fsbolero/bolero/wiki/Templating Configures the Elmish program in the Bolero client application to support hot reloading. This is achieved by chaining the Program.withHotReloading method, typically within a DEBUG build. ```fsharp type MyApp() = inherit ProgramComponent() override this.Program = Program.mkSimple (fun _ -> initModel) update view #if DEBUG |> Program.withHotReloading #endif ``` -------------------------------- ### Catch-all Path Parameters with Asterisk in F# Source: https://github.com/fsbolero/bolero/wiki/Routing Illustrates the use of an asterisk (`{*parameter}`) within an `EndPoint` attribute to capture the remainder of a URL path. This is useful for handling variable-length path segments, such as tags or file paths, and must correspond to string, list, or array types. ```fsharp type Page = | [ ListTagged of user: string * tags: list] Tagged("tarmil", ["bolero"; "webassembly"]) // -> /list/tarmil/tagged/bolero/webassembly ``` -------------------------------- ### Tuple Type Mapping to Path Fragments Source: https://github.com/fsbolero/bolero/wiki/Routing Illustrates how tuple types can be directly mapped to URL paths. The elements of the tuple correspond to consecutive fragments of the path, maintaining their order. ```fsharp type Page = int * string // -> /42/abc ``` -------------------------------- ### Define Bolero Remoting Service Interface Source: https://github.com/fsbolero/bolero/wiki/Remoting Defines the structure of a remote service in Bolero.Remoting. It specifies functions that take one argument and return an `Async<_>`. The `BasePath` property determines the URL endpoint for the service's functions. Arguments can be passed as tuples. ```fsharp open Bolero.Remoting type MyService = { getEntry : string -> Async> // Served at /myService/getEntry setEntry : string * string -> Async // Served at /myService/setEntry deleteEntry : string -> Async // Served at /myService/deleteEntry } interface IRemoteService with member this.BasePath = "/myService" ``` -------------------------------- ### Invoke Bolero Template Type Provider with HTML File Source: https://github.com/fsbolero/bolero/wiki/Templating Shows how to define an F# type alias for an HTML template by referencing an external HTML file. The type provider reads the file content. This is suitable for larger or more complex HTML structures. ```fsharp type Hello = Template<"hello.html"> let hello = Hello().Elt() ``` -------------------------------- ### List and Array Type Mapping to Path Fragments Source: https://github.com/fsbolero/bolero/wiki/Routing Explains how lists and arrays are represented in URL paths. The path begins with a fragment indicating the number of items, followed by individual fragments for each element in the list or array. ```fsharp type Page = list // -> /3/abc/def/ghi ``` -------------------------------- ### Two-Way Data Binding with bind.input in F# Source: https://github.com/fsbolero/bolero/wiki/HTML Demonstrates how to implement two-way data binding for input elements in F# using the `bind.input` function. This function binds the element's value to a model property and updates the model on user input. ```fsharp type Model = { username: string } type Message = | SetUsername of string let hello model dispatch = input [ bind.input model.username (fun n -> dispatch (SetUsername n)) ] ``` -------------------------------- ### Default Path Construction for F# Union Types Source: https://github.com/fsbolero/bolero/wiki/Routing Explains how a simple path fragment in `EndPoint` can lead to default path construction for F# union types. If the path is a single non-parameter fragment, the union's values are appended sequentially as path fragments. ```fsharp type Page = | [] // Equivalent to /list/{user}/{page} BlogList of user: string * page: int // -> /list/tarmil/1 ``` -------------------------------- ### Invoke Bolero Template Type Provider with HTML String Source: https://github.com/fsbolero/bolero/wiki/Templating Demonstrates how to define an F# type alias for an HTML template using a plain HTML string. The type provider infers the structure from the string. This method is recommended for simple HTML snippets. ```fsharp type Hello = Template<"""
Hello, world!
"""> let hello = Hello().Elt() ``` -------------------------------- ### Blazor Component with Parameters Source: https://github.com/fsbolero/bolero/wiki/HTML Shows how to add parameters to a Blazor component using the `Parameter` attribute from `Microsoft.AspNetCore.Blazor`. The component uses the provided parameter to customize its output message. ```fsharp type MyComponent() = inherit Component() [] member val Who = "" with get, set override this.Render() = div [] [text (sprintf "Hello, %s!" this.Who)] ``` -------------------------------- ### Bolero Nested Templates for Reusable UI Components Source: https://github.com/fsbolero/bolero/wiki/Templating Explains how to define and use nested templates within a single HTML file using the `