Views
Views are svelte components exported by app/exports.server.ts and/or app/exports.client.ts .


Server Exports
Views that are meant to be rendered on the server should be exported by app/exports.server.ts .
import Welcome from '$lib/views/welcome.svelte'
import Profile from '$lib/views/profile.svelte'
export const views = {
    "Welcome": Welcome,
    "Profile": Profile,
}


Client Exports
Views that are meant to be rendered on the client should be exported by app/exports.client.ts .
export const views = {
    "Welcome": () => import('$lib/views/welcome.svelte'),
    "Profile": () => import('$lib/views/profile.svelte'),
}
Note
These views are being imported asynchronously in order to split them in different bundles, however you can simply create fake promises in order to bundle them all together and eliminate network latency when transitioning between views.
import Welcome from '$lib/views/welcome.svelte'
import Profile from '$lib/views/profile.svelte'
export const views = {
    "Welcome": () => Promise.resolve(Welcome),
    "Profile": () => Promise.resolve(Profile),
}
Note
Keys in app/exports.server.ts and app/exports.client.ts are not mutually exclusive.
You can render the same component on both the server and the client at the same time.


Send Views
Use send.View() to send a view.
package welcome

import (
    "main/lib/core/clients"
    "main/lib/core/send"
    "main/lib/core/views"
)

func View(client *clients.Client) {
    send.View(client, views.View{Name: "Welcome"}) // Sends view "Welcome".
}
The Name of the view will be used to lookup the view component exported by app/exports.server.ts and/or app/exports.client.ts .

Default View
There is no way to specify a "default view”. However, you can use send.RequestedFile() in order to send the requested file or run custom logic if it doesn’t exist.
package welcome

import (
    "os"

    "main/lib/core/clients"
    "main/lib/core/send"
    "main/lib/core/views"
    "main/lib/routes/welcome"
)

func View(client *clients.Client) {
    if !send.RequestedFile(client) { // Tries to send the requested file, or else...
        welcome.View(client)         // ...sends the welcome view.
    }
}
Usually you would map this handler to the default GET / pattern, which automatically captures all unmatched requests.
package main

import (
    "embed"
    "main/lib/core/clients"
    "main/lib/core/servers"
    "main/lib/routes/welcome"
)

//go:embed app/dist
var efs embed.FS
var server = servers.New()                              // Creates server.

func main() {
    defer servers.Start(server)                         // Starts server.
    server.Efs = efs                                    // Sets embedded file system.
    server.Routes = append(server.Routes, routes.Route{ // Adds route to the server.
        Pattern: "GET /",
        Handler: welcome.View,
    })
}


View Properties
Optionally, you can specify properties for your View with the Props field.
package welcome

import (
    "main/lib/core/clients"
    "main/lib/core/send"
    "main/lib/core/views"
)

func View(client *clients.Client) {
    send.View(client, views.View{ // Sends view.
        Name: "Welcome",          // Sets view name.
        Props: map[string]string{ // Sets view props, which will be injected into the svelte component.
            "name": "world",      // Adds property "name" with value "world".
        },
    })
}
These properties are passed down to your view component.
<script lang="ts">
    type Props = { name: string }
    let {name}:Props = $props() // Retrieves view props.
</script>

<Title  text="Hello {name}"/>
Note
View properties are initialized with $state() and thus are reactive by default.


Render Modes
You can choose how to render views by setting one of 3 values for the RenderMode field in your View .

1
RenderModeFull
Using RenderModeFull , the view is rendered on both the server and the client.
This is the default mode.
package welcome

import (
    "main/lib/core/clients"
    "main/lib/core/send"
    "main/lib/core/views"
)

func View(client *clients.Client) {
    send.View(client, views.View{        // Sends view.
        Name: "Welcome",                 // Sets view name.
        RenderMode: view.RenderModeFull, // Renders view on server and client.
    })
}
2
RenderModeServer
Using RenderModeServer , the view is rendered only on the server.
You’ll have to deal away with apis such as fetch; your new best friend is form.
package welcome

import (
    "main/lib/core/clients"
    "main/lib/core/send"
    "main/lib/core/views"
)

func View(client *clients.Client) {
    send.View(client, views.View{          // Sends view.
        Name: "Welcome",                   // Sets view name.
        RenderMode: view.RenderModeServer, // Renders view only on server.
    })
}
Tip
While using RenderModeServer the view won’t serve a JavaScript bundle, but you can still use the <svelte:head> special tag in order to load scripts dynamically.
3
RenderModeClient
Using RenderModeClient , the view is rendered only on the client by loading a JavaScript bundle asynchronously.
package welcome

import (
    "main/lib/core/clients"
    "main/lib/core/send"
    "main/lib/core/views"
)

func View(client *clients.Client) {
    send.View(client, views.View{          // Sends view.
        Name: "Welcome",                   // Sets view name.
        RenderMode: view.RenderModeClient, // Renders view only on client.
    })
}
Tip
You can combine any of these render modes with adaptive hyperlinks and forms.
Read more about web standards.