How can one add custom http headers to Nuxt __page__ ( not static asset ! ) in Nuxt dev server? - http-headers

https://github.com/hyperbotauthor/vue-chessground/tree/main/test
My problem is that I have to add custom headers to my Nuxt page in order that SharedArrayBuffer may work.
I know how to add custom headers to assets served from the static folder and to the production server:
render: {
static: {
setHeaders(res) {
res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp')
res.setHeader('Cross-Origin-Opener-Policy', 'same-origin')
},
},
dist: {
setHeaders(res) {
res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp')
res.setHeader('Cross-Origin-Opener-Policy', 'same-origin')
}
}
},
However in dev server these headers are not added to the Nuxt pages served from the pages folder.
If I hand write an HTML page in the static folder, then SharedArrayBuffer will work on that page. But not on the Nuxt page.
Is there any way to make Nuxt dev server add headers to Vue rendered pages?
EDIT:
If I include the hand written, in separation working HTML in an iframe from the Vue page, then it again won't work.
EDIT:
I opened an issue at Nuxt:
https://github.com/nuxt/nuxt.js/issues

You also need to add the headers to the response for pages as well. Try testing using Postman or something similar to view response headers, when you try to load the static resources, as well as the nuxt pages.
Setting render: { static: ... } in nuxt.config.ts worked for the static resources.
To set up middleware for the server creating the initial html pages you can do:
// middleware/setSameOriginHeader.ts
export default function (req: any, res: any, next: any) {
res?.setHeader('Cross-Origin-Embedder-Policy', 'require-corp')
res?.setHeader('Cross-Origin-Opener-Policy', 'same-origin')
}
// nuxt.config.ts
export default {
ssr: false,
...
// middleware to set headers on pages
serverMiddleware: ['~/middleware/setSameOriginHeaders.ts'],
// set headers on resources in static dir
render: {
static: {
setHeaders(res: any) {
res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp')
res.setHeader('Cross-Origin-Opener-Policy', 'same-origin')
}
}
},
...
}

Related

Static page within dynamic nested route not generated on NuxtJS

My goal is to have the following page structure
pages
--/users/
--/users/:id/
--/users/:id/edit/
edit should be generated for every :id. Right now my setup works only in development mode. On nuxt generate only the first /users/:id/edit/ is generated. All other routes get a 404 error on production!
Current setup:
- /users
- index.vue
/_id
- index.vue
- edit.vue
I also tried to add another _id.vue which i found in the documentation and here
/users
- _id.vue
- /id
[...]
I checked this as well.
In nuxt.config.js I have
ssr: true,
target: 'static',
Do I need to add something in router property in nuxt.config.js? I am not sure why it is not generated in production.
If you are using static site generation you have to define your static routes, because Nuxt does not know how many users do you have in your data base.
You can set a generate method into your nuxt.config.js file:
generate: {
fallback: true,
async routes() {
const routes = await _getRoutes()
return routes
}
}
And then declare a function called _getRoutes to generate a list of dynamic routes:
async function _getRoutes($content) {
const usersList = [1, 2, 3] // get from your DB
const paths = []
usersList.forEach((userId) => {
paths.push(`/users/${userId}`)
paths.push(`/users/${userId}/edit`)
})
return paths
}
this is a bug with nuxt 2 in vue 2.
for dynamically generated routes, and also not-english nested routes ,
(or maybe just generally non-english routes) when vue hydrates the component , it will face a problem and restarts it . so the data that you cached in data(){} with fetch(), will be empty again .
currently you should use static and/or english-only routes .

Vue static assets are not accessible to a library

I am using a single file Vue component and import a face-api library. I want to use a function from that library, loadSsdMobilenetv1Model(url), which takes URL of folder, where the necessary files are located and loads them. The function however cannot fetch the files if I use #/assets/weights as url (# in Vue represents the src folder). I would like to be able to host the assets for. I'm able to read files from the assets folder folder with require('#/assets/file.json), but the library seems to need a static url.
What is the best solution in my situation? Maybe I'm missing some understanding.
Can I make it so that the assets folder is served and accessible?
Here's my component and the comments show some things I've tried:
<template>
<div>...stuff...</div>
</template>
<script>
import * as faceapi from 'face-api.js';
async function load() {
// example below: If I serve the files on a separate port with CORS allowed, the function loads files fine.
// const MODEL_URL = 'http://127.0.0.1:8081/weights/';
// example below: this does not work, but I would like this to work!
const MODEL_URL = '#/assets/weights';
// example below: also doesn't work, conscious of relative paths
// const MODEL_URL = '../assets/weights';
// example below: a file loads, but I can't just this unfortunately
// return require('#/assets/file.json')
return await faceapi.loadSsdMobilenetv1Model(MODEL_URL);
}
export default {
mounted() {
var promise = load();
promise.then((model) => {
this.model = model
}, (reject) => {
console.log(reject)
// alert(reject);
})
},
name: "Home",
data() {
return {
model: null
}
}
};
</script>
I'm not sure if it's relevant, but I set up the project with
vue create
and run the dev environment with
nmp run serve

Refresh statically generated page (data) once it has loaded on client

For example I have some page in Nuxt:
data() {
return {
items: []
};
},
asyncData() {
return axios.get('site.com/url')
.then((response) => {
return {
items: response.data
};
});
},
Then I run npm run generate and get statically generated html-page with data (items) from backend server. And when I open this page in browser I see that injected data into the page.
But these items might be updated on the backend so I need to see them once I have got refreshed the page with F5 and without running again npm run generate.
So looks like I should refetch data in mounted() section. Maybe Nuxt has something more suitable for this?
The only option is use crawler: false property in your nuxt.config.js file. It will disable static content generation from you dynamic pages. Here is the documentation.

Add static text in html generated by nuxt

I have a nuxt app, and I want to create static html files for all my routes.
I generate my static files successfully.
So after run nuxt generate I have e.g. these folders with index.html inside:
buy/apple
buy/orange
buy/banana
My problem is here.
In my page I want to have this:
<h1>Buy {{fruit_name}}</h1>
and I want fruit_name be static on generated html file.
so e.g. for apple in final html I want to have:
<h1>Buy apple</h1>
for now apple is empty.
So what should I do to set this variable base on route name on generate time.
assume my routes are constant and I set my routes on nuxt.config.js
UPDATE
I try to change them in generated html files, but when I serve it changes not applied. Why?
I found solution:
When generating routes pass payload to related page:
{
route: `/fruit/${name}`,
payload: { fruitName: name }
},
and set data in asyncData hook:
async asyncData({ params, error, payload }) {
if (payload) {
return {
name: payload.name
}
}
}
and here a data set in component and can access it through component and it is static and set in generated html file for each route.

Nuxt.js env Property, understanding and how to use it?

following https://nuxtjs.org/api/configuration-env
I have been trying to set up my apiUrl in nuxt.config.js once for the whole project, like:
export default {
env: {
apiUrl: process.env.MY_REMOTE_CMS_API_URL || 'http://localhost:1337'
}
}
adding this in nuxt.config.js, I'd expect (and would like) to have apiUrl accessible everywhere in the project.
In particular, it is needed for the 3 following cases:
with axios, to generate static pages from dynamic urls (in nuxt.config.js)
generate: {
routes: function () {
return axios.get(apiUrl + '/posts')
.then((res) => {
return res.data.filter(page => {
return page.publish === true;
}).map(page => {
return {
route: '/news/' + page.slug
}
})
})
}
},
with apollo, to get data via graphql (in nuxt.config.js)
apollo: {
clientConfigs: {
default: {
httpEndpoint: apiUrl + '/graphql'
}
}
},
in every layout, page and components, as the base url of media:
<img :src="apiUrl + item.image.url" />
As you might see, only thing I need is to 'print' the actual base url of the cms.
I have also tried to access it with process.env.apiUrl, with no success.
The only way I was able to make it has been to create an extra plugin/apiUrl.js file, which injects the api url, and seems wrong to me as I am now setting the apiUrl twice in my project.
I asked this question in the past, but in a way less clear way. I was suggested to use dotenv, but from the docs it looks like adding an additional layer of complication that might not be necessary for a simpler setup.
Thanks.
I think dotenv module really is what you need.
This is my setup:
Project root has a .env file that contains
BASE_URL=https://www.myapi.com
require('dotenv').config() at top of nuxt.config.js
#nuxtjs/dotenv installed and added to buildModules of nuxt.config.js
env: { BASE_URL: process.env.BASE_URL} added to nuxt.config.js
axios: { baseURL: process.env.BASE_URL } added to nuxt.config.js (optional)
You should have access to your .env throughout the project. (process.env.BASE_URL)
I haven't used apollo, but you should be able to set the apollo endpoint with process.env.BASE_URL + '/graphql'
As of Nuxt 2.13, #nuxtjs/dotenv is not required anymore. Read here
The concept that I was missing is that you set up the same named variable in your server / pipeline, so that you have your (always local / never pushed) .env file and a same name variable remotely, not added to your repo (where the value can be the same or different)