SSR and Vuex meta data
-
@PeterQF Did you try the code I posted? It should work to fix the meta tag issue.
-
@beets , yes i have and i get:
response: undefined,
isAxiosError: true,when i skip:
if (!ssrContext) {…
-
@PeterQF What if you try to use the full URL here:
return axiosInstance.get('api/site/getPostObj', {
i.e.
https://example.com/api/site/getPostObj
-
@beets i need to include API key in header so this is my code in boot/axios.js:
´´´
const axiosInstance = axios.create({
baseURL: process.env.PROD
? ‘https://api.lsvab.se’
: ‘http://api-lsvab.lndo.site’,
timeout: 180000,
headers: {
‘X-Client-Api-Key’: ‘XXXXXXXXXXXXXXXXXXXXXXXXXX’,
‘Content-Type’: ‘application/json’
}
})
´´´ -
@PeterQF I see. What I can say for sure is that you don’t want
if (!ssrContext) {
in your prefetch, or the meta tags won’t work. We need to figure out why axios gives an error, can you provide the full output (from the terminal window running quasar dev) if you put a console.log here:async preFetch ({ store, currentRoute, previousRoute, redirect, ssrContext }) { try { const payload = { post_slug: currentRoute.params.post } await store.dispatch('posts/setPostObj', payload) } catch(error) { console.log(error) redirect('/error') } },
-
@PeterQF Also, do you control that API endpoint? Is it possibly checking for a hostname to equal some value? If so, you may need to set the host header:
const axiosInstance = axios.create({ baseURL: process.env.PROD ? 'https://api.lsvab.se’' : 'http://api-lsvab.lndo.site', timeout: 180000, headers: { 'X-Client-Api-Key': 'XXXXXXXXXXXXXXXXXXXXXXXXXX', 'Content-Type': 'application/json', 'Host': 'frontendurl.com' } })
Of course, setting Host only can be done in the server process. I don’t think it will affect anything being there on the client, but if so, you’d just have to check which environment you’re in and conditionally add it. I.e
if(process.env.SERVER)
-
@beets ok so if i understand you correct preFetch is to be used on both client and server page load?
Adding Host: ‘api-lsvab.lndo.site’
gives me:
Refused to set unsafe header “Host”
-
@beets WOW, major breakthrough.
Turned out that my local env had a problem with Axios calls in preFetch due to Lando/Docker.
Removing
if (!ssrContext) {
works great on production server and https://metatags.io/ shows all meta correct.
Thank you so much for making me focus on preFetch.
I will just figure out how to “allow” Axios calls to local Lando/Docker API or maybe just disable preFetch locally since the meta isn´t that important under development.
-
By the way, console.log(error) when running preFetch in my dev env gives me this error:
Error: connect ECONNREFUSED 172.20.0.4:80 at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1054:14) { errno: 'ECONNREFUSED', code: 'ECONNREFUSED', syscall: 'connect', address: '172.20.0.4', port: 80, config: { url: 'api/site/getPostObj', method: 'get', headers: { Accept: 'application/json, text/plain, */*', 'X-Client-Api-Key': 'XXXXXXXXXXXXXXXXXX, 'Content-Type': 'application/json', 'User-Agent': 'axios/0.21.0' }, params: { post_slug: 'produktunderkategori-nyhet' }, baseURL: 'http://api-lsvab.lndo.site', transformRequest: [ [Function: transformRequest] ], transformResponse: [ [Function: transformResponse] ], timeout: 180000, adapter: [Function: httpAdapter], xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', maxContentLength: -1, maxBodyLength: -1, validateStatus: [Function: validateStatus], data: undefined }, request: Writable { _writableState: WritableState { objectMode: false, highWaterMark: 16384, finalCalled: false, needDrain: false, ending: false, ended: false, finished: false, destroyed: false, decodeStrings: true, defaultEncoding: 'utf8', length: 0, writing: false, corked: 0, sync: true, bufferProcessing: false, onwrite: [Function: bound onwrite], writecb: null, writelen: 0, bufferedRequest: null, lastBufferedRequest: null, pendingcb: 0, prefinished: false, errorEmitted: false, emitClose: true, autoDestroy: false, bufferedRequestCount: 0, corkedRequestsFree: [Object] }, writable: true, _events: [Object: null prototype] { response: [Array], error: [Function: handleRequestError], timeout: [Function] }, _eventsCount: 3, _maxListeners: undefined, _options: { maxRedirects: 21, maxBodyLength: 10485760, protocol: 'http:', path: '/api/site/getPostObj?post_slug=produktunderkategori-nyhet', method: 'GET', headers: [Object], agent: undefined, agents: [Object], auth: undefined, hostname: 'api-lsvab.lndo.site', port: null, nativeProtocols: [Object], pathname: '/api/site/getPostObj', search: '?post_slug=produktunderkategori-nyhet' }, _ended: true, _ending: true, _redirectCount: 0, _redirects: [], _requestBodyLength: 0, _requestBodyBuffers: [], _onNativeResponse: [Function], _currentRequest: ClientRequest { _events: [Object: null prototype], _eventsCount: 7, _maxListeners: undefined, outputData: [], outputSize: 0, writable: true, _last: true, chunkedEncoding: false, shouldKeepAlive: false, useChunkedEncodingByDefault: false, sendDate: false, _removedConnection: false, _removedContLen: false, _removedTE: false, _contentLength: 0, _hasBody: true, _trailer: '', finished: true, _headerSent: true, socket: [Socket], connection: [Socket], _header: 'GET /api/site/getPostObj?post_slug=produktunderkategori-nyhet HTTP/1.1\r' + '\nAccept: application/json, text/plain, */*\r' + '\nX-Client-Api-Key: XXXXXXXXXXXXXXXXX\r' + '\nContent-Type: application/json\r' + '\nUser-Agent: axios/0.21.0\r' + '\nHost: api-lsvab.lndo.site\r' + '\nConnection: close\r' + '\n\r' + '\n', _onPendingData: [Function: noopPendingOutput], agent: [Agent], socketPath: undefined, method: 'GET', path: '/api/site/getPostObj?post_slug=produktunderkategori-nyhet', _ended: false, res: null, aborted: false, timeoutCb: null, upgradeOrConnect: false, parser: null, maxHeadersCount: null, _redirectable: [Circular], [Symbol(isCorked)]: false, [Symbol(outHeadersKey)]: [Object: null prototype] }, _currentUrl: 'http://api-lsvab.lndo.site/api/site/getPostObj?post_slug=produktunderkategori-nyhet', _timeout: Timeout { _idleTimeout: -1, _idlePrev: null, _idleNext: null, _idleStart: 29830654, _onTimeout: null, _timerArgs: undefined, _repeat: null, _destroyed: false, [Symbol(refed)]: null, [Symbol(asyncId)]: 796876, [Symbol(triggerId)]: 796873 } }, response: undefined, isAxiosError: true, toJSON: [Function: toJSON] }
any idea how to solve this?
-
@PeterQF I’m not really well versed in docker. Is your SSR server and API server on different containers I suppose? You may need to set something with hosts to allow the SSR process to reach the API.
For me, without docker, I set baseURL to 127.0.0.1:8000 on the server, and https://api.example.com client. So if you can access the api with an internal network IP that could work, as long as docker is set up right. In this case you would have four checks:
If production and is server
If production and is client
If staging and is server
If staging and is clientAnd choose a host name / ip that can be reached on each of those cases.
As for the Host header, if you weren’t restricting api calls by that header, you don’t need it. But if you are, then just don’t set that on client. What I would do is some like:
const axiosConfig = {
headers:{
// your api key, and common stuff
}
}if(process.env.SERVER) {
axiosConfig.headers.Host = “frontendurl.com”
if(process.env.NODE_ENV === “development”) {
axiosConfig.baseURL = “something”
} else {
axiosConfig.baseURL = “something else”
}
} else {
// repeat dev or prod check from above
}On mobile, excuse any typos
-
@PeterQF also, yes, prefetch runs on either client or server. Initial page load causes prefetch to happen on server, while navigating to that page after the initial load causes it to happen on the client
-
So guys,
This is how i solved this.Turned out that Lando/Docker needed another base url when connecting to server with preFetch so the simple solution was to use this code for baseURL:
baseURL: process.env.PROD ? 'https://api.lsvab.se' : process.env.SERVER && process.env.DEV ? 'http://api-server.apilsvab.internal:8000' : 'http://api-lsvab.lndo.site',
Hope it can help anyone using Lando/Docker.
-
The problem with docker is that binding to the 127.0.0.1:xxx will not work - you must bind to 0.0.0.0:xxx. It is well known trap
-
Well,
Pure Docker might accept 0.0.0.0:xxx but not using Lando.
With Lando one has to connect to xxx.internal:xxxxJust like with DB connection: DB_HOST=default.postgres96.internal
-
Connection target and binding one are different things. At docker you must bind server to 0.0.0.0 and connect client using node host address which is usually internal to docker network
-
@Sfinx i’m sorry if i mix things up.
I’m really not that skilled with Docker, that is why i use Lando as it takes care of all this.
Just had to figure out how Lando wants me to do Axios calls in different situations.