Building small, reusable components and composing them into larger components is a great way to build a web application that is used by many client side JavaScript frameworks today. It would be great for this to be brought to Razor/Blazor but to also blur the lines between the client and server too.
Following on from this thread talking about static file handling. Perhaps the Vue.js concept of single file components could be taken to the extreme, so Blazor could handle a HTML template, server side Razor, client side Blazor and CSS all in one file (or separated if you'd like but in my experience if you make your components small and reusable, a single file really works well) with the C# being shared and runnable on the client and server side. I envisage something like this:
@Model Customer
<template>
<p>HTML which can be rendered on the client using Blazor or the Server using Razor.</p>
<p>@Customer.Name</p>
</template>
<style>
p {
font-size: 20px;
}
</style>
<script>
public class Customer
{
public string Name { get; set; }
}
this.Model = new Customer() { Name = "Server Rendered" }
this.window.OnLoad += (sender, e) =>
{
this.Model.Name = "Client Rendered";
};
</script>
The HTML would be prerendered on the server and show the customer name as 'Server Rendered'. When the event handler fires, the model text is changed to 'Client Rendered'.
There would need to be some sort of build system to extract CSS into a separate file, compile the C# code for the server using Razor but also for the client into web assembly format using Blazor. Finally the HTML template would also need to be compiled to C# as it is today for Razor but also for Blazor.
Making use of such a component could just use the web component standards, so it might look something like this:
@addComponents "ExampleComponent, MyAssemblyName"
@addComponents "*, MyOtherAssemblyName"
<template>
<h1>Using the component below</h1>
<example-component />
</template>
Thanks for the suggestion! I'll get some other folks on the team to discuss.
At the moment our plan for server-side rendering is to limit it to cases where you have .NET on the server. In that case we can trivially just execute the same components on the server like we do on the client. We don't need developers to specify different "templates" for server and client-side use, or at least not in general (there will be cases where you want to use DI to inject server variants of services that differ from client variants). Our existing architecture is designed with this in mind, so it should be very easy to enable, use, and have excellent performance.
Perhaps the Vue.js concept of single file components could be taken to the extreme, so Blazor could handle a HTML template, server side Razor, client side Blazor and CSS all in one file
We're already working with this in mind. The idea is that you can optionally have C# code-behind files for your components if you want, but equally well you can put your C# into a @functions { ... }
block in the Razor .cshtml
file and it works the same. As for how you'd declare CSS styles in the same file, well we haven't decided on a specific syntax for that but it follows that if you can do @functions { ... }
for C# you should probably be able to do @style { ... }
or @css { ... }
or something like that.
So overall, your proposal is pretty close to what we are aiming for!
I'll mark this closed since I hope it addresses your points. Let me know if not!
That sounds really great.
It sounds like you are on the same page as me. So C# code is shared between the client and server but with the ability to run extra code on the client or server wher necessary.
I'm not sure how I feel about the use of more Razor @foo { }
syntax instead of HTML wrapper tags. I personally think it would be one less thing to learn to use the standard template
, script
and style
HTML tags instead of coming up with new Razor commands like @style
.
Keep us posted, I'd really like to see a blog post showing some variants of this so the community can give feedback!
@deepness187, this is a github issue comment thread. If you can see this, I think it would be best if you came onto this link:
https://github.com/aspnet/Blazor/issues/173
Because your comments are open to the public and you may not appreciate them being public given what you have said and the place in which you have said it.
I think a general idea behind using the at syntax is that it lets you have a distinction between a pages javascript functions and the pages blazor functions.
Most helpful comment
@RehanSaeed I鈥檓 truly sorry that you have suffered a public and personal abusive attack from an individual just because of your name. I post this here because I would like github and the community to +1 to show support and to let that individual know vile personal attacks aren鈥檛 welcome.
@Eilon thanks for removing those comments, hope/trust the individual has been reported to github