{"id":13596496,"url":"https://github.com/keithn/dotnetviteguide","last_synced_at":"2026-01-16T08:06:14.336Z","repository":{"id":39374970,"uuid":"434081492","full_name":"keithn/dotnetviteguide","owner":"keithn","description":"Guide to getting started with .NET 6, Vite, and Vue 3","archived":false,"fork":false,"pushed_at":"2022-07-13T22:48:10.000Z","size":29,"stargazers_count":94,"open_issues_count":3,"forks_count":12,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-11-06T19:44:58.577Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/keithn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-12-02T04:29:52.000Z","updated_at":"2024-11-06T17:43:38.000Z","dependencies_parsed_at":"2022-07-14T03:40:30.949Z","dependency_job_id":null,"html_url":"https://github.com/keithn/dotnetviteguide","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keithn%2Fdotnetviteguide","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keithn%2Fdotnetviteguide/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keithn%2Fdotnetviteguide/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keithn%2Fdotnetviteguide/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/keithn","download_url":"https://codeload.github.com/keithn/dotnetviteguide/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248067945,"owners_count":21042385,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T16:02:29.907Z","updated_at":"2026-01-16T08:06:14.311Z","avatar_url":"https://github.com/keithn.png","language":null,"readme":"# A guide to getting started with ASP.NET Core 6, Vite, and Vue 3\n\nThis guide shows how to setup your environment for development.  While there are some templates for [ASP.NET Core 6](https://docs.microsoft.com/en-us/aspnet/core/?view=aspnetcore-6.0) and [Vue](https://vuejs.org/), it's often not really what you want.  This guide will show you how to hack your project to get it to run your frontend how you want.  You can use the information here and make variations for whatever tooling you like to use.\n\n# Goal for this guide\n\n- Setup a ASP.NET Core 6 project with a Vue 3 SPA front end\n- Use [Yarn](https://yarnpkg.com/) as my package manager\n- Use [Vite](https://vitejs.dev/) to generate the Vue project and run the development server\n- Customize the .NET publish to publish your Vite project\n\n# Tools I'm using\n\nWhile you can all kinds of different editors and tools and operating systems, for reference here is my setup\n\n- JetBrains Rider\n- Windows 11\n\n# Let's go!\n\n## Create a new ASP.NET Core project\n\nThere are a number of templates that you could use, but for this guide use the React template.\n```\ndotnet new react\n```\nin Rider\n\n![image](https://user-images.githubusercontent.com/86080/144359457-c1485bff-7d36-4a57-ad55-b346ebca480f.png)\n\nThis project will give you a good starting point and will setup the SPA proxy.\n\n## Small overview of the ASP.NET Core SPA proxy\n\nIn previous .NET versions (before .NET 6) dotnet projects setup a development proxy from the .NET [Kestrel](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-6.0) web server to your frontened project (whether it be Vue, React, Angular or other).  I never used this as it was silliness, I always manually setup the proxy the other way round, so proxy from my Vue app to the .NET API backend.  Thankfully, in .NET 6 this is the approach they now also use.\n\nSo now, the SPA development proxy isn't so much of a proxy, it is more of a SPA launcher, the main guts you can find here:\n\nhttps://github.com/dotnet/aspnetcore/blob/main/src/Middleware/Spa/SpaProxy/src/SpaProxyLaunchManager.cs\n\nIt is pretty simple and will help you understand what it is trying to do.\n\nThe general process is that it checks to see if your front is already running, and if it isn't, it attempts to launch it.\n\nMore annoyingly, it force kills it when your program ends.  It provides no option not to do this, and most often this is not what you want.  If you want to change your .NET project, such that you need to stop it and restart it, quite often you don't want your frontend to stop and start, so if you prefer, rather than letting your dev tools launch your front end, just manually launch it yourself in a terminal, i.e.\n\nIf you use yarn:\n```\nyarn dev\n```\nIf you use npm:\n```\nnpm run dev\n```\n\nHowever, we will setup the project to correctly run the SPA development proxy (i.e., launcher) properly.\n\n## Remove the ClientApp folder\n\nUnder your newly created .NET project, it will have a ClientApp folder. This has all the React code in it. Delete it.\n\n## Create your Vue 3 project with Vite\n\nIn the main project folder (where the csproj file is), run the following command to create a Vite project (or whatever tooling you want to use, as long as it makes a subfolder off the main project folder)\n\nIf you use yarn:\n```\nyarn create vite\n```\n\nOr if you use npm:\n```\nnpm create vite@latest\n```\n\nIt will ask you for the project name, this will be the name of the folder it creates, choose something you like, or you can call it ClientApp, which means you need to configure a bit less later.\n\nSelect the options you want. \n\nIn my case `vue -\u003e vue-ts`.\n\nchange into the directory, and type `yarn` to install dependencies or `npm install` if you use npm (or let your dev tools do it if they know how)\n\nYou can treat this project like a normal Vue 3 / Vite project and set it up however you like.  We will have to configure some options for Vite which we will discuss a little later in the guide.\n\n\n## Configure the .NET project\n\nNow that we have the Vite project we need to make some changes to the .NET project.\n\nChoose a port you want to run your Vite Vue project on (I tend to choose a unique port per project), in this case port 3399. The default port used by Vite is port 3000.\n\n```xml\n\u003cSpaProxyServerUrl\u003ehttps://localhost:3399\u003c/SpaProxyServerUrl\u003e\n```\n \nset the launch command for dev mode, in this case `yarn dev` (or `npm run dev` if you use npm)\n```xml\n\u003cSpaProxyLaunchCommand\u003eyarn dev\u003c/SpaProxyLaunchCommand\u003e\n```\n \nIf you have a different name for your project folder rather than \"ClientApp\" specify it in the SpaRoot\n```xml\n\u003cSpaRoot\u003eClientApp\\\u003c/SpaRoot\u003e\n```\n \nWhich should result in a project file something like below\n\n```xml\n\u003cPropertyGroup\u003e\n    \u003cTargetFramework\u003enet6.0\u003c/TargetFramework\u003e\n    \u003cNullable\u003eenable\u003c/Nullable\u003e\n    \u003cTypeScriptCompileBlocked\u003etrue\u003c/TypeScriptCompileBlocked\u003e\n    \u003cTypeScriptToolsVersion\u003eLatest\u003c/TypeScriptToolsVersion\u003e\n    \u003cIsPackable\u003efalse\u003c/IsPackable\u003e\n    \u003cSpaRoot\u003eClientApp\\\u003c/SpaRoot\u003e\n    \u003cDefaultItemExcludes\u003e$(DefaultItemExcludes);$(SpaRoot)node_modules\\**\u003c/DefaultItemExcludes\u003e\n    \u003cSpaProxyServerUrl\u003ehttps://localhost:3399\u003c/SpaProxyServerUrl\u003e\n    \u003cSpaProxyLaunchCommand\u003eyarn dev\u003c/SpaProxyLaunchCommand\u003e\n    \u003cImplicitUsings\u003eenable\u003c/ImplicitUsings\u003e\n\u003c/PropertyGroup\u003e\n```\n\n## Certificate for your Vue project\n\nBy default we generally want to use https for everything, so for your Vite project we can use \"makecert\" https://github.com/liuweiGL/vite-plugin-mkcert\n\nIf you use yarn:\n```\nyarn add vite-plugin-mkcert -D\n```\nOr if you use npm:\n```\nnpm install --save-dev vite-plugin-mkcert\n```\n\nand configure it like so\n\n```ts\nimport mkcert from 'vite-plugin-mkcert'\n\nexport default defineConfig({\n  plugins: [vue(), mkcert()],\n  server: {\n    https: true\n    //  the rest of the config...\n  }\n});\n```\n\n## Proxy from Vite to ASP.NET Core API\n\nNow lets setup the Vite proxy. Use the same port you chose back when editing the project, in this case port 3399.\n\n`strictPort` means it won't try another port if it finds that the port is already in use.  \n\nI suggest nesting all API calls under the route `/api` which makes it easy to work out what things to proxy. However, if you want to, you can rewrite the routing to the backend.  You mostly don't want to do this, otherwise in production you will end up with different routes and the two projects won't marry together without some other kind of config to set the correct routes.  However, I include the rewrite in the example below for reference (currently it doesn't change the route at all), you can omit the rewrite rule altogether if you aren't doing anything fancy.\n\nIn the proxy specify the `target` as whatever the .NET project has chosen for running the API on.\n\n`secure: false` just means the proxy won't check certificates, as we don't really care for our local setup (though if you've installed the dotnet developer certificate, it should be ok).\n\n\nvite.config.ts (or .js if you go with JavaScript)\n\n```ts\nimport { defineConfig } from 'vite'\nimport vue from '@vitejs/plugin-vue'\nimport mkcert from 'vite-plugin-mkcert'\n\nexport default defineConfig({\n  plugins: [vue(), mkcert()],\n  server: {\n    port: 3399,\n    https: true,\n    strictPort : true,\n    proxy: {\n      '/api' : {\n        target: 'https://localhost:7153',\n        changeOrigin: true,\n        secure: false,\n        rewrite: (path) =\u003e path.replace(/^\\/api/, '/api')\n      }\n    } \n  }\n})\n```\n\nRead more on [configuring Vite](https://vitejs.dev/config/).\n\n### ASP.NET Core minimal API and fetching from Vue\n\nIn your `Program.cs` file add a route that returns some test data\n\n```csharp\napp.MapGet(\"api/test\", () =\u003e new { Test = \"hello\" });\n```\n\nand in Vue, in your `App.vue` file, you can use the following template to test whether you can fetch the data :-\n\n```vue\n\u003cscript setup lang=\"ts\"\u003e\nimport { onMounted, ref } from \"vue\";\n\ninterface TestData {\n  test: string;\n}\n\nconst result = ref\u003cTestData\u003e({test: \"\"})\nonMounted(async () =\u003e {\n  result.value = await (await fetch(\"/api/test\")).json();\n});\n\n\u003c/script\u003e\n\n\u003ctemplate\u003e\n  \u003cdiv\u003eResult: {{ result.test }}\u003c/div\u003e\n\u003c/template\u003e\n```\n\n\n### Windows 11 / Windows Terminal \n\nBy default (at time of writing), the Windows Terminal does not automatically close.  However in the terminal settings you can change it so it closes on exit (no matter the exit reason)\n\n![image](https://user-images.githubusercontent.com/86080/144360255-2ce34b66-773f-4396-aa08-ff347f5e42a7.png)\n\nOtherwise it will leave a lot of stray terminals around.\n\n\n## Good to Develop!\n\nAt this stage everything should work in your development environment and you should be able to write code and have it proxy to your ASP.NET Core backend.\n\nIf you have any issues, or something is unclear or notice any problems with getting to this point, raise an issue on this repo and I will try to improve the guide!\n\n## Publish\n\nIn the `.csproj` file change:\n```xml\n\u003cDistFiles Include=\"$(SpaRoot)build\\**\" /\u003e\n```\nto:\n```xml\n\u003cDistFiles Include=\"$(SpaRoot)dist\\**\" /\u003e\n```\n\nTO BE CONTINUED....\n","funding_links":[],"categories":["Others","miscellaneous"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkeithn%2Fdotnetviteguide","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkeithn%2Fdotnetviteguide","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkeithn%2Fdotnetviteguide/lists"}