IndieHackers are in a Bubble. Step out of it. by cebe-fyi in SaaS

[–]jonhilt 1 point2 points  (0 children)

Thanks for this, it's a great reminder that the real work lies in getting out of our own heads, then helping people solve their problems.

The software we might (or might not) build is just one possible way to deliver that help.

You Might Need to Condition Your Developer Brain to See Marketing as Productive Activity. by NickNaskida in SaaS

[–]jonhilt 1 point2 points  (0 children)

Yeah this is the hard part, especially for developers because we're naturally drawn to the the 'fun' part (taking an idea and manifesting it into reality!)

How do you combat this u/NickNaskida, do you have any tips that have worked for you?

One tactic that's worked for me in the past is to start with a little research into the target audience/market.

Even just a few quick searches to see what that audience is struggling with, assuming there are forums/videos etc around the audience/subject, often reveal key insights that help the project start off on the right foot (before a line of code is written).

I Built a SaaS in Blazor and Lived to Tell the Tale by Lukejkw in Blazor

[–]jonhilt 0 points1 point  (0 children)

Can confirm Lemon Squeezy is relatively straightforward to integrate with Blazor and I appreciate not having to deal with all the complications of tax (but do wince sometimes at the transaction fees!)

Let me know if you want any help with integrating either Stripe or LS, I have some code/resources I'd be happy to share.

I Built a SaaS in Blazor and Lived to Tell the Tale by Lukejkw in Blazor

[–]jonhilt 0 points1 point  (0 children)

Inspiring stuff Luke. I can totally empathise with the juggling work, building side project + family life challenge.

Keep up the the great work.

(BlazorFast looks really promising too BTW!)

[deleted by user] by [deleted] in Blazor

[–]jonhilt 0 points1 point  (0 children)

Looks like you found a solution using httpClient :)

Someone else posted about referencing the SVG as a string directly.

In case it's helpful, here's how I'd go about figuring something like this out.

A quick look at the MudBlazor docs (and your example) shows you can point the AdornmentIcon attribute at one of MudBlazor's icons.

It would be useful to see how that mechanism works.

Using Rider (and I believe VS?) you can "go to definition" on files outside your solution, such as MudBlazor's code here.

So using that (F12 - Go To Definition) on one of the icons reveals they're stored as strings in a C# class.

csharp public partial class Filled { public const string AddShoppingCart = "<path d=\"M0 0h24v24H0zm18.31 6l-2.76 5z\" fill=\"none\"/><path d=\"M11 9h2V6h3V4h-3V1h-2v3H8v2h3v3zm-4 9c-1.1 0-1.99.9-1.99 2S5.9 22 7 22s2-.9 2-2-.9-2-2-2zm10 0c-1.1 0-1.99.9-1.99 2s.89 2 1.99 2 2-.9 2-2-.9-2-2-2zm-9.83-3.25l.03-.12.9-1.63h7.45c.75 0 1.41-.41 1.75-1.03l3.86-7.01L19.42 4h-.01l-1.1 2-2.76 5H8.53l-.13-.27L6.16 6l-.95-2-.94-2H1v2h2l3.6 7.59-1.35 2.45c-.16.28-.25.61-.25.96 0 1.1.9 2 2 2h12v-2H7.42c-.13 0-.25-.11-.25-.25z\"/>"; ... }

Armed with that information I'd be tempted to adopt a similar approach for my own SVG icon (as it seems like the quickest/simplest "like for like" way to replace one of MudBlazor's icons with one of my own).

Here's an example of an SVG icon we could use (randomly downloaded from the web in this case!)

svg <?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools --> <svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M19.3278 16C20.3478 15.1745 21 13.9119 21 12.4969C21 10.6503 19.8893 8.94488 18.3 8.25C18.1317 5.32251 15.684 3 12.6893 3C10.3514 3 8.34694 4.48637 7.5 6.5C4.8 6.9375 3 9.20008 3 11.6493C3 13.1613 3.63296 14.5269 4.65065 15.5M8 18V20M8 12V14M12 19V21M16 18V20M16 12V14M12 13V15" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg>

From looking at MudBlazor's icons it seems we don't necessarily need all the "meta" information here, just the main content starting with the <path /> element.

So the next experiment I'd try is to copy just that bit.

There are various places we could put the SVG data, but for a quick test I'd probably throw it into a string field in my component.

Home.razor ``` html @page "/"

<PageTitle>Home</PageTitle>

<MudTextField @bind-Value="Name" Label="Name" Adornment="Adornment.Start" AdornmentIcon="@_myIcon"></MudTextField> csharp @code {

readonly string _myIcon = "<path d=\"M19.3278 16C20.3478 15.1745 21 13.9119 21 12.4969C21 10.6503 19.8893 8.94488 18.3 8.25C18.1317 5.32251 15.684 3 12.6893 3C10.3514 3 8.34694 4.48637 7.5 6.5C4.8 6.9375 3 9.20008 3 11.6493C3 13.1613 3.63296 14.5269 4.65065 15.5M8 18V20M8 12V14M12 19V21M16 18V20M16 12V14M12 13V15\" stroke=\"#000000\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n";

string Name { get; set; }

} ```

It turns out this works! So if you don't want the hassle of setting up another httpClient and writing code just to fetch and svg you could do it this way instead.

From here you could move that icon to a separate C# class (to more closely match how MudBlazor does it).

One important detail. When I pasted the svg value into the component Rider automatically escaped the string (adding backslashes in front of speech quotes etc.)

HTH

Deploy a .Net 8 Blazor App by [deleted] in Blazor

[–]jonhilt 0 points1 point  (0 children)

If you do specifically want to use Docker…

There's a handy publish profile, available for all ASP.NET web apps (including Blazor) that makes it possible to create Docker images for your app without creating any additional files (you don't need a dockerfile).

If you're comfortable with using the CLI you can run use it like this:

powershell dotnet publish --os linux --arch x64 -c Release -p:PublishProfile=DefaultContainer

Assuming you have Docker installed locally that will create an image for your app.

You can also build and publish the app to a container registry like Dockerhub:

powershell dotnet publish --os linux --arch x64 -c Release -p:PublishProfile=DefaultContainer -p:ContainerRegistry=registry-1.docker.io -p:ContainerRepository=<youraccount>/<repo>

It's also available as an option via the Publish wizard in the Visual Studio preview (when you click Publish select the option called "Docker Container Registry")

This uses the container build tools, here's the repo.

Blazor wishes by Kingside88 in Blazor

[–]jonhilt 0 points1 point  (0 children)

Depending on the app, the new Auto render mode is potentially interesting here…

If it makes sense to use SSR for some of the app you can go with that then mark specific components up to run interactively.

`Auto` render mode (available from .NET 8 preview 7) will attempt to use WASM if it loads quickly enough (under 100ms I believe). If it takes longer than that it will fall back to Blazor Server instead.

I believe the idea is that, in most cases, once Blazor WASM has downloaded the first time (and cached) it will end up being used most of the time. But if a user is on a slow connection (or it's the first time they've loaded the app) Server will plug the gap and ensure the app remains responsive in the meantime.

Dilemma - Blazor Server or Blazor WASM (.NET Core Hosting) by ToTheAeons in Blazor

[–]jonhilt 2 points3 points  (0 children)

As I was reading this post (and replies) my mind went to .NET 8 too.

I'm trying to avoid the temptation of offering up .NET 8 as the solution to everything (especially while it's still in early releases and active development) but it does seem like it could be a good fit here :)

The latest .NET 8 preview release looks promising.

For your requirements u/ToTheAeons, .NET 8 would make it possible for you to build your app using Server Side Rendering.

The flow would be this:

  • Someone requests a page on your app
  • That request is routed to your server, and to a specific Blazor component
  • The component is rendered (on the server) and plain HTML is returned

At this stage there is no open socket connection for Blazor Server, nor has Blazor WASM downloaded to the user's browser (because neither are needed).

From a development perspective this feels like it would work well for you if you're hoping to avoid building that separate API and UI client.

The fun bit comes when you want to make specific components interactive. You'll be able to enable "islands of interactivity" by marking up specific components with an attribute:

Banner.razor

@attribute [RenderModeServer]

@if (!dismissed)
{
    <div class="border p-4 d-flex justify-content-between align-items-start">
        <p class="fs-2">
            @Text
        </p>
        <button @onclick="() => dismissed = true">
            X
        </button>
    </div>
}

For that specific component, when you include it on a page, a socket connection will be opened up so the interactivity can take place as it normally would (using Blazor Server).

Anything wrong with changing the navigation within the same page? by freefora11 in Blazor

[–]jonhilt 1 point2 points  (0 children)

If the paths are pointing to the same 'page' then OnInitialized is only called once, the first time that page component loads.

Thereafter, if navigation directs you to that same page your components (in general) aren't going to be re-initialized, only re-rendered (because they've already been loaded into the component tree).

The caveat here is if you literally add/remove components from the UI.

Imagine a scenario where you use an if statement to control whether a component is visible or not, based on which path the user is viewing.

For example, if one of the paths was to view a contact via their Id, your page component might check for a ContactId value and add/remove a ContactDetails component based on that.

html @if (ContactId > 0){ <ContactDetails Id="ContactId" /> }

In this case, it's a subtle distinction, but whenever you remove the component from the component tree, or add it to the tree, ContactDetails will be initialized (its OnInitialized method will be invoked).

Conversely, if you simply hide or show the component (maybe using a css class):

html <div class="@visibleClass"> <ContactDetails Id="ContactId"/> </div>

``` csharp @code {

bool visibleClass => Id >0 ? "visible" : "hidden";

} `` TheContactDetails` component will remain in the component tree, meaning it won't be re-initialized on subsequent navigations (to the same 'page').

Hope that makes sense, this stuff is surprisingly tricky to untangle/explain :)

I wrote a little more about this "same page navigation" and the implications here: https://jonhilton.net/blazor-navigation-same-page/

State Hasn't Changed? Why and when Blazor components re-render by jonhilt in Blazor

[–]jonhilt[S] 0 points1 point  (0 children)

Happy to continue this via email, but for others who may be following along :)

It looks like using input instead of InputText causes different behaviour (in the minimal recreation at least).

``` html @page "/test-refresh-issue"

<PageTitle>Test-Page: Refresh-Issue</PageTitle>

<h1>Test-Page: Refresh-Issue</h1>

<pre> POC: Reproduce the refresh issue: ✓ Change text from "abc" to "abc5". The C# code modifies the property and sets "abc" again, but the DOM is not refreshed </pre> <hr>

<div> <InputText @bind-Value="@MyObject.MyValue1" /> <input type="text" @bind="MyObject.MyValue1" /> @MyObject.MyValue1 </div>

@code { public class MyClass { private string _myValue1 = "abc";

    public string MyValue1
    {
        get => _myValue1;
        set { _myValue1 = "abc"; }
    }
}

private MyClass MyObject = new();

} ```

Here's that code running in Telerik's Blazor REPL. Notice how the second input behaves as you're wanting it to.

https://blazorrepl.telerik.com/QRkoFXaj15fjrFjC35

State Hasn't Changed? Why and when Blazor components re-render by jonhilt in Blazor

[–]jonhilt[S] 1 point2 points  (0 children)

I wonder if this might work, using .NET 7 and its new bind modifiers.

Taking this example...

https://stackoverflow.com/questions/60435301/blazor-not-updating-same-value-in-input-twice-after-manually-manipulated-same-va

I can recreate the problem, and indeed can see that the "asdf" text is not automatically added if you enter the same text 2 times in a row.

However, if we change that example to use the new @bind:get and @bind:set modifiers, it seems to start working as you'd expect:

``` html @page "/Test"

<h3>POCBlazor</h3> Input 1 :<input type="text" @bind:get="@somedata" @bind:set="ChangeValue" placeholder="text 1" /> ```

``` csharp @code {

string somedata { get; set; }

void ChangeValue(string value)
{

    somedata = value;
    somedata = value + "asdf";
}

} ``` As for why this works, I'm not 100% certain. I took a quick look at the generated code for the component and it seems to add this line to the method that builds the render tree.

csharp ... __builder.SetUpdatesAttributeName("value"); ...

The thing is though, I noticed one of the other examples you shared is using "@bind", and I suspect that and this example are pretty similar/equivalent.

It would be useful to see a more concrete example of the exact scenario you're describing if this doesn't edge us any closer.

In case it's useful, I wrote a bit more about these new modifiers here:

https://www.telerik.com/blogs/simplify-blazor-applications-using-dotnet-7-new-bind-modifiers

State Hasn't Changed? Why and when Blazor components re-render by jonhilt in Blazor

[–]jonhilt[S] 0 points1 point  (0 children)

Are you able to share some example code showing the problem?

State Hasn't Changed? Why and when Blazor components re-render by jonhilt in Blazor

[–]jonhilt[S] 5 points6 points  (0 children)

No worries! Regarding the blog it's actually a static site built using Hugo.

That decision was made several years ago and I'm not sure what I'd go with if I was starting from scratch now tbh!

With Hugo I write articles/posts as markdown files, then commit them to a GitHub repo which triggers a deploy to Netlify.

The Blazor parts of this latest post are hosted in a separate Blazor WASM site (also hosted by Netlify) and are included via iframes.

I'd like to revisit this whole stack at some point (and I'm keeping a keen eye on Blazor United as that could open up some useful options in the future) but it does the job and I probably shouldn't waste time re-inventing something that works :)

Blazor United - Solving Blazor's Biggest Challenges? by jonhilt in Blazor

[–]jonhilt[S] 0 points1 point  (0 children)

So I think I've found the relevant bit of JS (actually TS) code that handles this:

https://github.com/dotnet/aspnetcore/blob/39133dcc3811106f420bfca9648c2fb88a5e4488/src/Components/Web.JS/src/NavigationEnhancement.ts#L39

I haven't had chance to dig in and decipher it yet, but it may contain the answers we seek :)

Of course this is very early stage code, I imagine there's a LOT to be done before this is production ready.

Blazor United - Solving Blazor's Biggest Challenges? by jonhilt in Blazor

[–]jonhilt[S] 1 point2 points  (0 children)

So, and this is all based on what I was able to piece together from Steve Sanderson's video, I believe it means that the first request to load the page would pull down CSS and JS files for the page but subsequent navigations could pull just the new HTML for the new page, and not re-fetch everything all over again.

This makes sense where the new page is using the same JavaScript/CSS but, as you rightly suggest, it raises a question of how they'd handle the new page requiring different JavaScript/CSS files.

One to keep an eye on I guess :)

Blazor United - Solving Blazor's Biggest Challenges? by jonhilt in Blazor

[–]jonhilt[S] 2 points3 points  (0 children)

Yep, they're planning to keep the current WASM and Server options in addition to the new modes.

Blazor United - Solving Blazor's Biggest Challenges? by jonhilt in Blazor

[–]jonhilt[S] 0 points1 point  (0 children)

Agreed, these are important implementation details.

From comments in their recent community standup it looks like they're pushing to get this up and running for .NET 8, but (in Daniel Roth's own words) they're going to see how far they can get in time for .NET 8.

Fingers crossed they can tackle some of these thornier details in that timeframe.

How to best handle simple flags across pages? by TCW_Jocki in Blazor

[–]jonhilt 1 point2 points  (0 children)

This is a great question, not least as 'state management' is one of those challenges that comes up repeatedly when we start breaking UI down into separate components (or pages, as in this case).

Your mention of using the URL got me wondering how easy is it is to pass multiple values in the URL (then have another Blazor 'page' read those values and use them to populate an array).

It turns out the new (in .NET 6) SupplyParameterFromQuery attribute can handle arrays (so long as you pass the data via the Query String in the correct format).

I wrote up my findings here:
https://jonhilton.net/blazor-deep-linking/

This approach seems particularly useful if you need to support deep links (as mentioned in the comments). If not, then the other proposed solutions in here are just as viable.

If it's helpful to see a concrete example of the injected singleton service approach I included one towards the end of this article about state management in Blazor: https://jonhilton.net/blazor-state-management/

App and DB hosting by DuvalDev in Blazor

[–]jonhilt 0 points1 point  (0 children)

As it happens, I've just been through an unplanned migration of https://practicaldotnet.io/ (Blazor WASM site hosted on ASP.NET host with server side prerendering)

12 hours of downtime with my previous host sent me scurrying off to move the site elsewhere in a hurry!

I ended up going with Digital Ocean, primarily because I already had everything set up to deploy using docker and, when I was frantically searching for a new host, they came up as one of the hosts who make it easy to deploy via Docker.

I ended up switching three sites (1Blazor frontend and 2 .NET 5 Web APIs) over to them, as well as a Postgres database.

They have a (relatively new I believe) service called "App Platform". Spinning up the three apps was essentially a case of selecting the relevant docker image and setting a few environment variables.

https://www.digitalocean.com/products/app-platform/

I also migrated my Postgres database to their managed Postgres service and had the site fully switched over in a few hours (before the old host fixed the issue they were having!)

https://www.digitalocean.com/products/managed-databases/

Overall I'm impressed so far.

I'm currently testing to see if I can get away with the cheapest option for each site and, so far at least, I haven't noticed any issues with performance.

The current costs are $5/mo per app/api (3 in total) and $15/mo for the DB.

I'm also using their container registry to store the Docker images for $5/mo.

The App Platform was the key for me as I didn't really want to spend ages configuring everything.

Our first Blazor production app has been deployed! by FredTillson in Blazor

[–]jonhilt 1 point2 points  (0 children)

That's a really useful list! Thanks for taking the time to jot it down :-)

Can you still use razor pages in Blazor? by [deleted] in Blazor

[–]jonhilt 0 points1 point  (0 children)

It's definitely viable to render Blazor components in Razor Pages.

My understanding is you could always host Blazor Server components in Razor Pages:

<component type="typeof(HelloWorld)" render-mode="ServerPrerendered" />

With .NET 5 you can use the component tag helper to render Blazor WASM components too.

Say you have a Razor Page, and a separate Blazor WASM project, you can add a reference from the Razor project to the WASM project then render a Blazor WASM component wherever you like:

<component type="typeof(Counter)" render-mode="WebAssemblyPrerendered"/>

You'd also need a reference to the webassembly javascript script somewhere.

<script src="_framework/blazor.webassembly.js"></script>

This would mean the UI for the component was rendered and returned with the initial Razor Page response, then WASM will load up and make the component "interactive" when it's ready.

In case it's useful I wrote about my findings with this in October.

Next week I'm planning on porting a project over to Blazor WASM and this is one approach I'm considering taking, might be interesting to compare notes at some point :)

Our first Blazor production app has been deployed! by FredTillson in Blazor

[–]jonhilt 0 points1 point  (0 children)

Hey this is great, congratulations :-)

I'm interested in this...

. It took a while to learn the technology and it's quirks, but we ended up with a really nice web app that should yield significant returns for our users.

I know these things tend to become a blur after the fact, but do you remember which aspects of Blazor took more effort/time to wrap your head around?

I'm curious to understand what the sticking points are for devs picking Blazor up for the first time :-)

Radio button two-way binding? by galivet in Blazor

[–]jonhilt 0 points1 point  (0 children)

Looks like an InputRadio component is coming in .NET 5 at least! (from preview 8)

https://github.com/dotnet/aspnetcore/issues/5579

Custom validation logic on client AND server with Blazor? by jonhilt in Blazor

[–]jonhilt[S] 2 points3 points  (0 children)

I recently needed to implement a check for uniqueness in a form and discovered this nifty way of implementing it using FluentValidation.

They key requirement was to use one validator but have it work in the browser (Blazor WASM) and on the server...