.NET WASM is still loading. You can interact in this page after it's fully loaded.

Current page is prerendered.

Get Started

Please check the samples for a quick start

This contains the code for the document site itself: https://github.com/slaveOftime/Fun.Blazor/tree/master/Fun.Blazor.Docs.Wasm.

This contains the code for Fun.Blazor templates, also with more samples in it: https://github.com/slaveOftime/Fun.Blazor.Samples.

Use dotnet templates:

Nuget 👈 always try to use the latest one.

dotnet new --install Fun.Blazor.Templates::4.0.2
dotnet new fun-blazor -o FunBlazorDemo1

Code structure example (just my opinionated way)

If you prefer blazor csharp official style, you can just use fun-blazor template to get started.

This project supports multiple patterns for state management. From my experience, it is not good to use Elmish for your whole project because of the performance and state share concern. Sometimes, it is a little verbose.

You can try this:

Db
Domain
Services
UI
|--- Stores.fs // contains shared store or global store

type IShareStore with // scoped for the session in blazor server mode
    member store.IsDark = store.CreateCVal("IsDark", true)

type IGlobalStore with // Singleton store, shared for all. Used in server-side blazor to share some data for all connected users.
    ...

|--- Hooks.fs // standalone UI logic

type IComponentHook with
    member hook.TryLoadPosts(page) = task {
        ...
    }

    member hook.UseSettingsForm() =
        hook
           .UseAdaptiveForm({| Name = "foo"; ... |})
           .AddValidators(...)
           .AddValidators(...)

|--- Controls.fs // Some small shared controls
|--- Comp1.fs // Your business component

// Make your fragment smaller, so you can compose it in a cleaner way and get better inline optimization, hot-reload speeding, and intellisense performance
let private fragment1 = div {...}

let private fragment2 (shareStore: IShareStore) =
    adaptiview {
        let! isDark, setIsDark = shareStore.IsDark.WithSetter()
        div { ... } 
    }

// Or use Elmish if you like
let private fragment3 = html.elmish (init, update, view)

let comp1 =
    html.inject (fun (svc1, shareStore: IShareStore, ...) ->
        div {
            fragment1
            fragment2 shareStore
            fragment3
        }
    )

|--- Comp2.Hooks.fs // in case you have a large component, or you can even create a separate folder for the whole component
|--- Comp2.Control1.fs // manage a large control which is only for your business Comp2
|--- Comp2.fs // The entry for your comp2
|--- App.fs // compose your components or pages

let private routes =
    html.route [
        routeCi "/page1" comp1
        routeAny comp2
    ]

let app =
    div {
        header
        routes
        footer
    }

|--- Index.fs // if you are using blazor server mode, you need to have this. You can check the template.
|--- Startup.fs