
The Struggle with Vue and ASP.NET Core
There is a wonderful template in Visual Studio to create a FullStack application that serves Vue 3 as the frontend and .NET core as the backend. Microsoft even provides a tutorial on it.

But as usual, once you want to customize, things get complicated.
I’ve spent hours trying to understand why I could not change the URL to hit the server, and I finally found the issue. It’s no surprise that this was a CORS and HTTPS/Certificate issue.
The project is pretty basic, and we will concentrate on these four files: HellowWorld.vue, vite.config.ts, WeatherForecastController.cs, and Program.cs.

In HelloWorld.vue, there is a fetchData() function.

And inside is a fetch()
call. This is important because, by default, this call hits the backend controller namespace VueApp1.Server.Controllers
.
This seems pretty straightforward, but everything will stop working if you change
var response = await fetch('weatherforecast');
to
var response = await fetch('/api/weatherforecast');
You may get a NETWORK_ERR
or a No Valid JSON
error, but to me it didn’t make sense why that was happening.
Even changing from a relative path to an absolute path (like below) did not resolve the issue.
var response = await fetch('https://localhost:7185/api/weatherforecast');
To understand this, we have to look at vite.config.ts
.

In here, some magic is happening; specifically, a server
is being setup/configured.
In here, there is a proxy
option. This is where the baseUrl
is being defined. The target is set just a few lines above as:
This little setup is really here to enable you to debug “easier” and not have to worry about certs or CORS at all. But to enable that, the system has some settings that matter. The biggest is this:
Do you remember the HelloWorld
file?
This is the endpoint that uses the server setup. With the target
URL set, the fetch
URL gets translated to: https://localhost:7185/weatherforecast
This will hit the corresponding controller in the backend, but everything broke when we changed this:
The issue was that we have to also change the server.proxy
configuration to this:
And then, of course, your controller also needs to be updated to have the corresponding route.

Running the app now should work again.
Great!
Just one more thing: it will break again when you try to hit the absolute URL.
WHY?
Because it’s not using the server configuration from before. As part of that configuration, there are certificates installed:
Those certificates are needed for SSL traffic in debugging.
Luckily, there is a simple fix: enable CORS in your backend for the port from the server (61402 in this case).

Adding that will allow you to use the absolute URL as well, and you could technically go without the Vue server setup.
That’s it!
It took me way too long to get to a running debugging state that made sense, so I wanted to share this, hoping it would save you some time and suffering.
Please note that this whole setup is for debugging/development only. At the very top of Server Options, it says:

So, you will still have to use real SSL configurations in your production environment, which is a good thing.