Trying to serve CRA build folder statically in asp.net core 2 - reactjs

I created a basic web api, and added a react frontend using create-react-app. When in production I want to serve the build folder which gets created by running npm run build from create-react-app statically. Based on what I found on the docs here, I tried the following, but to no avail. I get a 404, and nothing on screen.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsProduction())
{
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "client/build")),
RequestPath = "/static"
});
}
app.UseMvc();
}
Not sure where I am going wrong.

Related

ASP.NET Core - Serve both API and SPA React from different port

It is possible to serve both an API and a Single Page Application (SPA) React/Redux from different ports in ASP.NET Core. I found some post here ASP.NET Core - Serve both API and SPA from the same port that asks for serving from the same port, I would like to serve them on different ports because I would like to implement Azure B2C Authentication(so my spa can safely communicate with web api). I generated a boiler plate that includes react spa with .net web api but it is in one solution by default. Not sure if I should generate .net core web api and react app in a separate projects but when I run the application it serves both spa and webapi on the port that is configured in launchSettings.json for web api. In Startup.cs i have
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/build";
});
app.UseSpaStaticFiles();
app.UseSpa(spa =>
{
if (env.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
I tried to add "homepage": "https://localhost:3000",
to package.json of react.app I also tried to add spa.Options.DefaultPage = "https://localhost:3000"
I also tried spa.UseProxyToSpaDevelopmentServer("https://localhost:3000");
But none of that works. Is there something like a Nuget package or maybe some extra trick with configuration or should I give up on the boiler plate and create 2 independent projects(1 create-react-app and then generate a default web api project). Thanks
Different from the template for ASP.NET Core with React.js, React.js and Redux is using .net core3.1 so it doesn't have .env file. In that file you can set the running port of your project.
According to the MS document, I think React.js and Redux project is using middleware to compile the functions code first then put them to the static web page and display it. The following code do this part of job:
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
When you start the project in VS, you can see the port number in the browser, which is the running port of the whole project. So you think the API and SPA are running on the same port. From my perspective, API is using middleware to invoke SPA.
You can use command line code npm start in the ClientApp File to run the SPA as an independent project, it will run it on the default port 3000. Here is the screenshot of my test:

Deploy ASP.NET core 7 Web API with React front end

I wrote an ASP.NET Core 7 web API backend and standalone Javascript React front end. I can deploy the backend to IIS successfully and it works fine through postman. However when I try to deploy the react front end using the method described in this tutorial https://learn.microsoft.com/en-us/visualstudio/javascript/tutorial-asp-net-core-with-react?view=vs-2022
my visual studio just freaks out and crashes. I am trying to figure out how to deploy the front end manually without using the visual studio publish feature.
This is my project setup:
[1]: https://i.stack.imgur.com/cApdk.png
And this is the IIS side where the WEB API backend is currently published:
[2]: https://i.stack.imgur.com/GtJ9O.png
Do I need to create a separate site for the frontend or can I deploy it to the same site as the backend? How can I build the frontend and manually deploy to the IIS?
For the site to work properly, you should build the frontend part in production mode, i.e. use the command npm run build instead of npm run start.
And then move the resulting files to the wwwroot folder inside your NET7 project.
Additionally, you should add static files using the AddStaticFiles method.
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-7.0
Also remember to set the ports correctly, because you can have different ones in the development and production environment, you will do it in launchsetting.json
You just need to change your Program.cs file like below, the you could publish webapi project directly. Every step mentioned in the official document must be completed, and finally add the following code.
namespace WebApplication1
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
else
{
app.UseDefaultFiles();
//app.UseStaticFiles();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
//app.MapControllers();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
// Add this line
endpoints.MapFallbackToFile("/index.html");
});
app.Run();
}
}
}
Test Result

Nextjs api "pages/api" doesn't work on vercel server

Hello guys may you help me?
I'm trying to configure my fake API to create some personal projects but in my case, the method using the /pages/api folder only works for me in localhost when I deploy to the server on Vercel the project can't find my endpoints.
In my case I'm using the src/ folder method to develop my app and I don't know if this structure can cause problems with api folder.
One thing that I tried and worked is deploying to vercel using the api folder at the root of the application (out of /src folder) but the api stop working on localhost.
This structure works on localhost but doesn't work on server:
├───public/
├───src/
├───api/
├───pages/
...
next.config.js
package.json
This structure works on server but doesn't work on localhost:
├───api/
├───public/
├───src/
├───pages/
...
next.config.js
package.json
This is the method that I'm using to get data:
AXIOS API:
import axios from 'axios'
const api = axios.create({
baseURL: '/api/'
})
export default api
SWR HOOK:
import api from 'src/services/api'
import useSWR from 'swr'
function SwrFetchHook<Data = any, Error = any>(url: string) {
const { data, error } = useSWR<Data, Error>(url, async url => {
const response = await api.get(url)
return response.data
})
return { data, error }
}
export default SwrFetchHook
SWR callback:
const { data } = SwrFetchHook<INavItem[]>('categories')
I hope that I could explain, my question here is how is the best way to work with this feature because the /src folder is common to use with nextjs but I don't know if this is the real problem with the api folder.
Thanks!
Not 100% sure if this is the same issue. I had this warning in my build phase:
warn - Statically exporting a Next.js application via `next export` disables API routes. This command is meant for static-only hosts, and is not necessary to make your application static.
Make sure you are using the correct build command in out package.json scripts.
I'm my case:
"next build && next export" needed to be changed to "build": "next build"
Note: I removed && next export
This disabled the static export feature and allowed the use of pages/api when running yarn start note: yarn start relies on the build script within Vercel's build pipeline. So do not override the default settings unless it is needed.
Also normal Node/JS projects you can define a source folder in the scripts area ie "start": "<SOME_COMMAND> ./src"....but Next.js does this automatically so I do not think having an src file is the issue. I too have an src file in my project and it is a very common way (preferred way) of organizing your JS project. You shouldn't have to touch this if you are using next.
I tried deploying my app on digital ocean and it worked cuz vercel was not providing a server. I was not able to call my api from POSTMAN as well. Deployed it on digitalOcean and then it ran a server just like my localhost.

Any Suggestions for getting ASP.NET Core + React Running on Elastic Beanstalk

I'm trying to get an ASP.NET Core with ReactJS application deployed to Amazon's Elastic Beanstalk. I've been using this tutorial to help me get started. I can deploy the tutorial (using the dotnet new web template) project just fine. However, when I publish a ASP.NET Core + React project (using dotnet new react template), I get the following exception when trying to access the application:
InvalidOperationException: The SPA default page middleware could not return the default page '/index.html' because it was not found, and no other middleware handled the request.
Your application is running in Production mode, so make sure it has been published, or that you have built your SPA manually. Alternatively you may wish to switch to the Development environment.
This only occurs when I try to access ClientApp/ React components. When I access an API endpoint, there is no problem.
Additionally, this does not occur when running locally. Running locally works fine.
To reproduce this error, I've executed the following:
dotnet new react -o test-react/
dotnet publish test-react/ -o site/
cd site/
zip ../deploy.zip *
Finally, I manually import deploy.zip into AWS Elastic Beanstalk.
This is the Startup.cs file for that project.
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
// In production, the React files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/build";
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
}
}
For reference, I am targeting .NET Core 3.1. Any ideas on how to solve this problem? I believe I've tried everything suggested on this GitHub issue. Any help would be greatly appreciated.
This question seems similar but is obviously for Angular and not React:
deploy Angular/Asp.Net Core 2.1 app to AWS: 500 error
It turns out that my deploy.zip package wasn't being created recursively so files in subdirectories were missing. Instead of doing,
zip ../deploy.zip *
I did,
zip -r ../deploy.zip *
which worked as intended. Silly me.

How to deploy Next.js app without Node.js server?

I was hoping to deploy a Next.js app with Laravel API. I had developed React apps with CRA and in those I used the API server to serve the index.html of the CRA as the entry point of the app.
But in Next.js, after development I get to know that it needs a Node.js server to serve (which is my bad, didn't notice that). There is an option next export that builds a static representation of the Next.js app and it has an index.html. I am serving the index.html as the entry of the app by my Laravel API. It is serving the page, but just some of the static contents.
What I was hoping to know is it possible to host the aPI and the Next app from a single PHP shared hosting without any node server? If so, how? If not so, what could be the alternatives?
Actually the acepted answer is completly wrong, when you do yarn build and in your package.json is set like "build": "next build && next export", you will get an out folder which all the items in there are used to build without node.js server
Now since you are using laravel, and you use the out folder you will only load half of the page because the routes are not set properly. for that to work you need to edit your next.config.js edit it to
module.exports = {
distDir: '/resources/views',
assetPrefix: '/resources/views',
}
These will set the root directory to the root one in Laravel. now this will work for SPA (single page application) only for the dynamic routes you need to match with a view file for each one that you have in your out folder
For each route that you have you need to create a new "get" route in laravel
Route::get('/', function () {
return require resource_path('views/index.html');
});
Route::get('/contacts', function () {
return require resource_path('views/contacts.html');
});
Route::get('/post/{slug}', function () {
return require resource_path('views/post/[slug].html');
});
Notice that you can pass a wildcard for dynamic routes and they are all gonna work. once you do that and you deploy route out folder inside /resources/views in Laravel it's going to work
Apparently there is no alternative to nodejs server, which is not an option for me currently, so I unfortunately had to abandon next.js and create a CRA app and used as much from the next.js as I could.

Resources