I'm building a react single page application using for backend, loopback.
How can I set, in the middleware, all the traffic (except API calls to the server and asset files like css, js,...) to go to index.html?
Here is what I have for the moment in my middleware.json configuration for the files page.:
"files": {
"loopback#static": [
{
"paths": [
"/storage"
],
"params": "$!../storage"
},
{
"paths": [
"/*"
],
"params": "$!../client/index.html"
},
{
"paths": [
"/*.*"
],
"params": "$!../client"
}
]
},
At the moment, it seems like all traffic is indeed redirected to index.html but so are the css, js, ...
Any ideas?
Related
I have been trying to deploy an a Flask API to vercel and I am getting error that routes[0].header should be an object.
I am a beginner and trying to figure this out, any help is appreciated
my vercel.json is
`
{
"version": 2,
"builds": [
{
"src": "./index.py",
"use": "#vercel/python"
}
],
"routes": [
{
"src": "/(.*)",
"dest": "/",
"headers": [
{
"key": "access-control-allow-origin",
"value": "*"
}
]
}
]
}
`
i deployed earlier without headers and it deployed successfully but it was giving me CORS error then i addded the headers and now it is giving me a new error that headers is not a object.
i tried a few different methods but i still can not figure this out
I encountered similar issue and after going through vercel documents https://vercel.com/guides/how-to-enable-cors and few different tries, this worked for me:
The header has to be its own key for specifying access-control-allow-origin and "routes" will need to be replaced with "rewrite" as header and route keys don't go together. And If there are few different domains for your app, you need to duplicate header object within the outer header array for each path for access control origin issue.
Eg:
{
"version": 2,
"builds": [
{
"src": "./index.py",
"use": "#vercel/python"
}
],
"rewrites": [
{ "source": "/(.*)", "destination": "src/app.js" }
],
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "Access-Control-Allow-Origin", "value": "*" }
]
},
{
"source": "/vercel_app_domain_name/(.*)",
"headers": [
{ "key": "Access-Control-Allow-Origin", "value": "*" }
]
}
]
}
As per the documentation i tried to merge my config files so they are a bit more readable. The generated ocelot.json file however is not like expected. My folder structure is like follows:
Folder structure
Below is a text representation of this:
.
└── Ocelot route configs
├── ocelot.pokemon.json
├── ocelot.tweet.json
└── ocelot.weather.json
The ocelot.pokemon.json file looks like following (the others are similar to this):
{
"Routes": [
{
"DownstreamPathTemplate": "/api/v2/pokemon",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "pokeapi.co",
"Port": 443
}
],
"UpstreamPathTemplate": "/api/pokemon",
"UpstreamHttpMethod": [ "GET" ],
"AuthenticationOptions": {
"AuthenticationProviderKey": "MyTestKey",
"AllowedScopes": []
}
},
{
"DownstreamPathTemplate": "/api/v2/pokemon/ditto",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "pokeapi.co",
"Port": 443
}
],
"UpstreamPathTemplate": "/api/pokemon/ditto",
"UpstreamHttpMethod": [ "GET" ]
}
]
}
The generated ocelot.json file looks like this:
{
"Routes": [
],
"DynamicRoutes": [
],
"Aggregates": [
],
"GlobalConfiguration": {
"RequestIdKey": null,
"ServiceDiscoveryProvider": {
"Scheme": null,
"Host": null,
"Port": 0,
"Type": null,
"Token": null,
"ConfigurationKey": null,
"PollingInterval": 0,
"Namespace": null
},
"RateLimitOptions": {
"ClientIdHeader": "ClientId",
"QuotaExceededMessage": null,
"RateLimitCounterPrefix": "ocelot",
"DisableRateLimitHeaders": false,
"HttpStatusCode": 429
},
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking": 0,
"DurationOfBreak": 0,
"TimeoutValue": 0
},
"BaseUrl": null,
"LoadBalancerOptions": {
"Type": null,
"Key": null,
"Expiry": 0
},
"DownstreamScheme": null,
"HttpHandlerOptions": {
"AllowAutoRedirect": false,
"UseCookieContainer": false,
"UseTracing": false,
"UseProxy": true,
"MaxConnectionsPerServer": 2147483647
},
"DownstreamHttpVersion": null
}
}
As you can see, the routes I defined were not added. I tried looking on the internet for this specific issue but couldn't find anything. I don't know what I'm doing wrong, help will be appreciated.
Since your different route configuration files are located in a folder you should make sure the correct overload of the AddOcelot method is called. In this case the method should be called with the folder name containing the route files.
For example:
config.AddOcelot("Ocelot route configs", hostingContext.HostingEnvironment)
UPDATE: .NET Core 3+ with Ocelot 17.0.0
As the method AddOcelot needs an IWebHostEnvironment, and this is not available in HostBuilderContext:
You need to get it via WebHostBuilderContext:
I created two different directories Development and Production and with the below code, I'm able to read ocelot configuration according to development environment to generate the final ocelot.json that will be use by ocelot middleware.
I've build a PWA with vue. Everything is working fine in development and when I deploy to chrome webserver. Service worker is registrated and running. So far so good.
When I deploy to production, service worker isn't running due to the fact that the scope or start_url is not matching manifest.json (thats what google dev tools tells me).
I believe it's due to the fact that I'm running vue-router in history mode and have a .htaccess file running on production to rewrite rules as recommended here.
I've also tested this to switch back to hash mode in vue-router and deploy to production again. Then service worker is working just fine.
To overcome this problem I've tried to set the scope in manifest.json and service worker to index.html:
register(`${process.env.BASE_URL}service-worker.js`, {
registrationOptions: { scope: 'index.html' },
ready () {
console.log(
'App is being served from cache by a service worker.\n'
)
}
})
The same for manifest.json:
{
"name": "myapp",
"short_name": "myapp",
"theme_color": "#4DBA87",
"icons": [
{ "src": "./img/icons/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "./img/icons/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" },
{ "src": "./img/icons/android-chrome-maskable-192x192.png", "sizes": "192x192", "type": "image/png", "purpose": "maskable" },
{ "src": "./img/icons/android-chrome-maskable-512x512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
],
"start_url": "index.html",
"scope": "index.html",
"orientation": "portrait",
"display": "standalone",
"background_color": "#000000"
}
But still chrome gives me the message about scope being not in sync.
Any thoughts on this?
Add to package.json config for pwa plugin:
"vue": {
"pwa": {
"workboxOptions": {
"exclude": [
".htaccess"
]
}
}
}
UPDATE:
This action excludes .htaccess file from SW cache.
So, your SW won't crash and won't attempt to download .htaccess file from server.
At least, I faced with same problem and found this StackOverflow topic without answer. So, I read Vue PWA doc and found this, working for me, way.
I have this configuration for serve (serve.json):
{
"headers": [
{
"source": "**/**",
"headers": [
{
"key": "Content-Security-Policy",
"value": "frame-ancestors 'none'"
},
{
"key": "X-Frame-Options",
"value": "deny"
}
]
}
],
"rewrites": [
{ "source": "/**", "destination": "/index.html" },
{ "source": "/logout", "destination": "/logout.html" }
]
}
When running 'serve build' (build being the folder where the html files are served from) and trying to access localhost/logout, I'm redirected to index.html.
The desired behaviour is to use logout.html when accessing logout route.
It looks like "/**" takes priority as every time I'm redirected to index.html.
Thank you
Though I hadn't yet confirmed it, have you considered reversing the order, so that the explicit rules (such as /logout) are earlier in the array than the implicit/wildcard rewrite rules (such as /**)?
I have successfully built my app and only remain step is deploy to the host Vercel via my repo on Gitlab
I use Nuxt.js(SSR type) with server Express.js and Nuxt.js Now Builder to deploy host Vercel via repo Gitlab
This is structure
api/
--| index.js
now.json
nuxt.config.js
In index.js
const express = require("express");
const app = express();
const bodyParser = require("body-parser");
const products = require("./routes/product/products");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// Import API Routes
app.use(products);
// Export the server middleware
module.exports = {
path: "/api",
handler: app
};
In now.json
{
"version": 2,
"builds": [
{
"src": "nuxt.config.js",
"use": "#nuxtjs/now-builder",
"config": {
"serverFiles": [
"package.json"
]
}
}
]
}
And in nuxt.config.js
...
serverMiddleware: [
// API middleware
"~/api/index.js"
]
...
According to Vercel documentation, deploying is very easy, just commit and push code to Gitlab to complete
However, i always get error as below
I don't understand why? I don't know what i missed. Please help me and i'm very grateful for the help
narze, thank you for your solution, unfortunately it didn't work for me but pointed me in the right direction.
Here is my working now.json:
{
"version": 2,
"env": {
"ON_VERCEL": "true"
},
"builds": [
{
"src": "api/**/*.js",
"use": "#now/node"
},
{
"src": "nuxt.config.js",
"use": "#nuxtjs/now-builder"
}
],
"routes": [
{ "src": "/api/(.*)", "dest": "api/index.js" },
{ "src": "/api", "dest": "api/index.js" },
{ "src": "/(.*)", "dest": "$1" }
]
}
serverMiddleware in nuxt.config.js
serverMiddleware: isServerlessEnvironment ? [] : [
'~/api/index.js'
],
where isServerlessEnvironment defined on the very top of nuxt.config.js as
const isServerlessEnvironment = process.env.ON_VERCEL=="true"
API files need to be compiled with #now/node.
Routes need to be set up to separate nuxt routes from api routes.
With conditional isServerlessEnvironment in nuxt.config.js it works on local server with yarn dev and vercel server.
Credits to this article: Nuxt.js with an Express.js API server running on Now.sh
Thank you all for being helpful :)
I have similar problem with deploying Nuxt on Vercel with serverMiddleware's which returned 405 (Not Allowed). I solved it using this doc Nuxt Vercel Builder by specifying property serverFiles in vercel.json:
{
"builds": [
{
"src": "nuxt.config.js",
"use": "#nuxtjs/vercel-builder",
"config": {
"serverFiles": ["server-middleware/**"]
}
}
]
}
If you need to include files in the server lambda that are not built
by webpack or within static/, such as a local module or
serverMiddleware, you may specify them with this option. Each item can
be a glob pattern.
I know it's a bit late now lol. But I wrote an article to demonstrate the whole process to get your app up and running on Vercel. You can find it here.