Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow sitelets to return SPAs #1403

Open
granicz opened this issue Apr 6, 2024 · 4 comments
Open

Allow sitelets to return SPAs #1403

granicz opened this issue Apr 6, 2024 · 4 comments

Comments

@granicz
Copy link
Member

granicz commented Apr 6, 2024

Now that we have a prototype for sitelet bundling, we have the capability to extend it over SPAs. For instance, given an SPA entry point:

type HomeTemplate = Template<"home.html", ClientLoad.FromDocument>

[<JavaScript>]
let HomePage() =
    ... // Page model, etc.
    MainTemplate()
        ... // Event handlers, placeholders, etc.
        .Bind()

... allow it to be served with its static HTML:

[<Website>]
let Main =
    Application.MultiPage (fun ctx -> function
        | EndPoint.Home ->
            Content.PageFromFile("home.html", Client.HomePage())
        ...

Here, the proposed Content.PageFromFile is akin to the current Page.Content: we generate a page bundle (a .js file named after the HTML file) and entrypoint code from the supplied quoted expression (Client.HomePage() above) to be automatically included in the response (into the usual "scripts" placeholder).

@Jand42
Copy link
Member

Jand42 commented Apr 8, 2024

@granicz I was thinking we can bring Sitelets/SPAs/Offline sitelets all together.
But Offline/SPA would have no dynamic content, it could only load data from server by RPCs to initialize itself. The point to use predefined html (compile-time generated for Offline and hand-written for SPA) is to not touch it when serving.
So this piece makes no sense: we can't serve a static file AND dynamic content at the same time - which one is it: Content.PageFromFile("home.html", Client.HomePage())

@granicz
Copy link
Member Author

granicz commented Apr 11, 2024

The point of Content.PageFromFile is to enable serving a potentially non-templated SPA from a sitelet. (Even for templated cases such as the one above, the server can compute the response much faster because it doesn't need to use UI templates for it.) As such, it involves an element of dynamism: while the response is based on a static HTML file, it's actually augmented with a script block that takes care of the after-load initialization, supplied by the second, quoted argument.

In a way, this is similar to serving a page with an OnAfterRender (OAR) function, without the need to add an OAR or even using UI templating.

The intended behavior is that each Content.PageFromFile establishes a unique bundle and the server references it at runtime when generating the response from the HTML file (first argument).

@Jand42
Copy link
Member

Jand42 commented Apr 11, 2024

@granicz I see, what should the bundle .js be named? From your use case, it seems you don't want to pre-bake the initialization into "home.html", and this would be looked up from app root, not web root (not a public file by itself).

So if you want to use the same html in multiple places, we could do this:

  1. by default put code for functions and argument deserializers used in all "home.html" initializations by Content.PageFromFile into a single home.js bundle
  2. also have an optional argument for bundle name, that would specify the .js name that could be different, and then you have smaller bundles when you reuse same html with different content

@granicz
Copy link
Member Author

granicz commented Apr 22, 2024

There would be near-zero chance for an HTML file to be used with multiple instantiations, so I'd just go with 1).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: v8.0
Development

No branches or pull requests

2 participants