After deploy projects configured with Vercel or Nextjs rewriting can't find assets path - reactjs

I have the following structure to use one domain to multiple projects:
A repo that contains a single vercel.json file to configure path to others projects
A repo that contains a home app example
A repo that contains a checkout app example
The vercel.json works pretty great and is deployed in nizen.com.br, here is how is it:
// vercel.json
{
"rewrites": [
{
"source": "/checkout",
"destination": "https://checkout.nizen.com.br/checkout"
},
{
"source": "/",
"destination": "https://home.nizen.com.br"
}
]
}
So if we go to nizen.com.br we get the home app example without styles and a bunch of errors in console trying to get the assets of home.nizen.com.br in nizen.com.br and the same happens to checkout app.
Here is one of the similar errors that appear in console on Home app:
And here is the checkout app:
About the app next.config.js files, only Home app stays untouched and Checkout app has a basePath added with value "/checkout" as follows:
// Checkout app next.config.js
module.exports = {
reactStrictMode: true,
basePath: "/checkout",
};
I have tried to use the Next rewrites in hope that will solve the problem but it didn't work.
// example of rewrite that I did
module.exports = {
async rewrites() {
return [
{
source: "/",
destination: "https://home.nizen.com.br",
},
];
},
};
I tried to pass :path* and :path in source and destination, as well use fallback and even change the destination to checkout app to see if something change and none of that worked.
If I got to https://home.nizen.com.br the app runs perfect and same to checkout. What am I doing wrong?

I have solved this question changing the strategy. Instead of using a repo with vercel.json to route the micro-frontends, I'm using the home app as the project hosted in nizen.com.br and it's next.config.js file is the one who makes the magic happen!
//Home App next.config.js file
module.exports = {
reactStrictMode: true,
async rewrites() {
return {
fallback: [
{
source: "/checkout",
destination: "https://checkout.nizen.com.br/checkout",
},
{
source: "/checkout/:path*",
destination: "https://checkout.nizen.com.br/checkout/:path*",
},
],
};
},
};
Both the source and destination must point to the same sub-path (/checkout) and both fallback blocks are necessary. I'm using Next version 12 by the time I'm writing this.

Related

Gatsby Cloud environment variables not working in production

In a Gatsby project hosted in Gatsby Cloud I'm passing an API key as an environment variables, but unfortunately it's not available...
The code looks like this:
import React, { useEffect, useState } from 'react';
import Airtable from 'airtable';
Airtable.configure({ apiKey: process.env.AIRTABLE_API_KEY });
const base = Airtable.base('appKjIv7utFmqAkdT');
function Gallery() {...
You can see where I'm inserting the API key.
My gatsby-config.js looks like this (I'm loading dotenv on top):
require('dotenv').config({
path: `.env.${process.env.NODE_ENV}`,
});
module.exports = {
siteMetadata: {
title: `wernergeller.com`,
siteUrl: `https://www.yourdomain.tld`,
},
plugins: [
{
resolve: 'gatsby-plugin-google-analytics',
options: {
trackingId: '123',
},
},
'gatsby-plugin-image',
'gatsby-plugin-sitemap',
'gatsby-plugin-sharp',
'gatsby-transformer-sharp',
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'images',
path: './src/images/',
},
__key: 'images',
},
],
};
Locally (gatsby develop) this is working well.
Any help is highly appreciated!
In Gatsby Cloud variables needs to be added in the dashboard. The URL is something like: https://www.gatsbyjs.com/dashboard/YOUR_ORGANIZATION_UUID/settings/general#env-vars
And visually:
You can add variables individually or in a bulk with key:value pair:
Keep in mind that if you have environment variables that need to be accessed in the browser rather than the server, you'll need to prefix with GATSBY_.
It looks that the Airtable configuration is set on the browser, so you will need to change the key to:
Airtable.configure({ apiKey: process.env.GATSBY_AIRTABLE_API_KEY });
Changing the environment variable accordingly in the process.env and in the Gatsby Cloud dashboard.
Test your site with gatsby build locally before pushing it because gatsby develop it's not a full representation of your built/compiled project.

webpack-dev-server - Remove URI fragment from URL when live reloading

I'm dealing with an Angular 1 application that uses URI fragments for routing purposes.
For example:
http://localhost:3000/#/home
http://localhost:3000/#/menu
http://localhost:3000/#/list
Rather than:
http://localhost:3000/home
http://localhost:3000/menu
http://localhost:3000/list
When I'm using Webpack Dev Server to launch a local server with hot reloading, every time I apply some changes, Webpack reloads the URL but keeping the "/#/route" part.
Unfortunately, due to some code restrictions, I need to always reload the page from "/" because some redirections are applied internally when the app launches the first time and the app will crash if you try to start directly from any URI fragment.
I tried to use the "proxy" and "historyApiFallback" configurations in webpack.config.js like:
devServer: {
proxy: {
'/#': {
target: 'http://localhost:3000',
pathRewrite: { '^/#': '' }
}
}
And:
devServer: {
historyApiFallback: {
verbose: true,
rewrites: [{ from: /^\/#/, to: '/' }]
}
}
But so far, I didn't have any luck. The URL keeps the hash when reloading.
Any suggestions or ideas to configure Webpack Dev Server to always start from "/" and remove the hash URI?

Module Federation for React host and NextJS remote app example/comfiguration

I didn't find an example for a react host with and nextjs remote app
My host is working with a react remote app, now that I'm trying to add a nextjs remote app, it's not working:
Ports:
Host 3000
React remote 3001
NextJS Remote 3002
In my host react app I have the following, in the webpack.config.js file
plugins: [
new ModuleFederationPlugin({
name: 'react_container',
filename: 'remoteEntry.js',
remotes: {
remote_react: 'remote_react#http://localhost:3001/remoteEntry.js', // <- This is working
remote_nextjs: 'remote_nextjs#http://localhost:3002/_next/static/chunks/remoteEntry.js', // <- Not working :-(
},
exposes: {
'./react': 'react',
'./react-dom': 'react-dom',
},
shared: {
},
}),
And in the remote nextjs app in the next.config.js file
const { withFederatedSidecar } = require("#module-federation/nextjs-mf");
module.exports = withFederatedSidecar({
name: "remote_nextjs",
filename: "static/chunks/remoteEntry.js",
exposes: {
"./ExposedComponent": "./components/ExposedComponent",
},
shared: {
},
})({
// your original next.config.js export
});
And finally, in the App.jsx of the host , I'm trying to consume the remote components like
import RemoteNav from 'remote_react/Nav'; // <- Working
import ExposedComponent from 'remote_nextjs/ExposedComponent'; // <- Not working
I have repo here
The error I'm getting its 404 from
http://localhost:3000/_next/static/chunks/components_ExposedComponent_js.js
Thanks
From the webpack config of the host, I can see that the next JS app is running on port 3002.
You are getting 404 error for next JS remote bundles when the host is trying to fetch the bundles from next JS server, it is hitting port 3000 instead of 3002. This is because the next.config.js does not have the updated publicPath.
Add the following in the place where it says //your original next.config.js export in the next.config.js file
webpack: (config) => {
config.output.publicPath = "http://localhost:3002/_next/";
return config;
}
This will set the publicPath of your next JS app to port 3002 and fetch the bundles correctly.
Referring to https://webpack.js.org/guides/public-path/ ,
on your remote app's webpack config, set publicPath would fix the path issue.
export default {
output: {
publicPath: 'auto',
},
plugins: [...],
...
}

How to proxy request in Docusaurus v2?

I'm trying to config my Docusaurus web app to proxy the request to my api endpoint. For example, if I make a fetch request in my app fetch(/api/test), it will proxy the request from localhost:3000/api/test to my {{api_endpoint}}/api/test, but I'm still struggling to do it.
What I've done:
add a proxy field in package.json
create a setupProxy.js in the src folder
These 2 are based on the Proxying API Requests in Development
Another approach way is I created a custom webpack plugin and add it to the Docusaurus config
Does anyone have experience on this problem ? Thanks for reading, I really appreciate your help.
I went down the exact same path. Ultimately Docusaurus runs its Webpack dev server under the hood which is why the proxy field and setupProxy.js were not working as expected. I was able to get the outside API call by proxy and solved CORS errors by creating a Docusaurs plugin like you are attempting. Adding the "mergeStrategy" and "changeOrigin" were the keys to getting it all working.
// plugins/webpack/index.js
module.exports = function (context, options) {
return {
name: "cusotm-webpack-plugin",
configureWebpack(config, isServer, utils) {
return {
mergeStrategy: { "devServer.proxy": "replace" },
devServer: {
proxy: {
"/YOUR_COOL_ROUTE": {
target: "https://YOUR_COOL_API/",
secure: false,
changeOrigin: true,
logLevel: "debug",
},
},
},
};
},
};
};

Matching root route in webpack-dev-server's historyApiFallback`

Sample repo demonstrating the issue is here.
I'm trying to set up webpack dev server so that:
Requests to / are served by public/landing.html (a static landing page)
Requests to anything else are served by my React app
Using create-react-app, and based on webpack-dev-server's options, I've set up my webpackDevServer.config.js as follows:
historyApiFallback: {
// Paths with dots should still use the history fallback.
// See https://github.com/facebookincubator/create-react-app/issues/387.
disableDotRule: true,
rewrites: [
// shows views/landing.html as the landing page
{ from: /^\/$/, to: 'landing.html' },
// shows views/subpage.html for all routes starting with /subpage
{ from: /^\/subpage/, to: 'subpage.html' },
// shows views/404.html on all other pages
{ from: /./, to: '404.html' },
],
},
And when I start webpack here's what I see:
Requests to /subpage are routed correctly to subpage.html
Requests to /foo are routed correctly to 404.html. Eventually, these would be handled by my React app.
Requests to / are routed incorrectly to my React app.
How can I get landing.html to respond to requests at /?
I ended up opening a bug request with webpack-dev-middleware and discovered it was not a bug but a failure of configuration.
Specifically, the issue is using HtmlWebpackPlugin alongside historyApiFallback. I believe plugins are processed before the regex matching, and HtmlWebpackPlugin's default file output is index.html; this means that out of the box, / will always be routed to the HtmlWebpackPlugin output file.
The solution to this is to set a custom filename in HtmlWebpackPlugin, which allows you to control the matching again. Here's a sample repo demonstrating the fix and here's the webpack config:
module.exports = {
context: __dirname,
entry: [
'./app.js',
],
output: {
path: __dirname + "/dist",
filename: "bundle.js"
},
devServer: {
publicPath: "/",
// contentBase: "./public",
// hot: true,
historyApiFallback: {
// disableDotRule: true,
rewrites: [
{ from: /^\/$/, to: '/public/index.html' },
{ from: /^\/foo/, to: '/public/foo.html' },
{ from: /(.*)/, to: '/test.html' },
],
}
},
plugins: [
new HtmlWebpackPlugin({
title: "Html Webpack html",
hash: true,
filename: 'test.html',
template: 'public/plugin.html',
}),
],
};
Two thoughts come to mind:
What you want to do is not possible with Webpack Dev Server (as far as I'm aware)
And, once npm run build is run and deployed the deployed app would not follow the same rules as configured in Webpack Dev Server
Even if I'm mistaken on #1, #2 seems like a bigger issue if you ever plan to deploy the app. This leads me to recommend an alternate setup which will work on dev and production (or wherever it's deployed).
A few options:
setup the app as a single-page app (SPA) and use React Router to serve the static routes (/ and /subpage) and wildcards (everything else)
setup node (or another server) to serve the static routes (/ and /subpage) and wildcards (everything else)
An Attempt
In an attempt to setup the routes I was able to achieve this setup:
Display landing.html when / is requested
Display subpage.html when /subpage is requested
Display the React App at a specific path, like app.html
To do this make the following changes:
Move /public/index.html to /public/app.html
mv ./public/index.html ./public/app.html
In /config/webpackDevServer.config.js, update historyApiFallback to:
historyApiFallback: {
// Paths with dots should still use the history fallback.
// See https://github.com/facebookincubator/create-react-app/issues/387.
disableDotRule: true,
rewrites: [
// shows views/landing.html as the landing page
{ from: /^\/$/, to: "landing.html" },
// shows views/subpage.html for all routes starting with /subpage
{ from: /^\/subpage/, to: "subpage.html" },
// shows views/app.html on all other pages
// but doesn't work for routes other than app.html
{ from: /./, to: "app.html" }
]
}
In /config/paths.js update appHTML to:
appHtml: resolveApp("public/app.html")
In /config/webpack.config.dev.js, updateplugins` to include:
new HtmlWebpackPlugin({
filename: "app.html",
inject: true,
template: paths.appHtml
})
Requesting a random URL, like localhost:3000/foo will return a blank page but contains the HTML from the app.html page without the bundled <script> tags injected. So maybe you can find a solution to this final hurdle.

Resources