So I'm getting a routing problem whenever I use nuxt ssr with serverless. When I use either deploy to AWS lambda or use serverless-offline it generates the url prefixed with /{stage}, but nuxt can't seem to handle this and either throws 403, 404 or 500 errors because the routes to static files aren't prefixed with /{stage}.
I have tried adding {stage} to the public path on build, the results in a 404 because now the static file path needs to prefixed with another /{stage}. If I go directly to {stage}/{stage}/_nuxt/{file} it works.
build: {
publicPath: '/{stage}/_nuxt'
}
So looking around I found that I can update the router base to the below
router: {
base: '/{stage}'
}
but now the file only loads if its {stage}/{stage}/{stage}/_nuxt/{file} and removing the publicPath code above doesn't make it work either.
And this is for the static files, when it comes to the actual routes the homepage set at '/' either works but any other pages don't because the nuxt-links to them aren't prefixed with /{stage} or if I add the prefix to the base I get a Cannot GET / error when I visit /{stage}.
I have tried many different ways of doing this such as using express however I have had no luck and any tutorials that I found online are at least 2 years old and the github repos have the same problem. The closest thing I have found on stackoverflow that is somewhat similar to what I have is here but this is for a static site.
Anybody have any ideas? Below is the code for the serverless.yaml, handler.js, nuxt.js, nuxt.config.js.
Github Repo
serverless.yaml
service: nuxt-ssr-lambda
provider:
name: aws
runtime: nodejs12.x
stage: ${env:STAGE}
region: eu-west-1
lambdaHashingVersion: 20201221
environment:
NODE_ENV: ${env:STAGE}
apiGateway:
shouldStartNameWithService: true
functions:
nuxt:
handler: handler.nuxt
events:
- http: ANY /
- http: ANY /{proxy+}
plugins:
- serverless-apigw-binary
- serverless-dotenv-plugin
- serverless-offline
custom:
apigwBinary:
types:
- '*/*'
handler.js
const sls = require('serverless-http')
const binaryMimeTypes = require('./binaryMimeTypes')
const nuxt = require('./nuxt')
module.exports.nuxt = sls(nuxt, {
binary: binaryMimeTypes
})
nuxt.js
const { Nuxt } = require('nuxt')
const config = require('./nuxt.config.js')
const nuxt = new Nuxt({ ...config, dev: false })
module.exports = (req, res) =>
nuxt.ready().then(() => nuxt.server.app(req, res))
nuxt.config.js
module.exports = {
telemetry: false,
head: {
htmlAttrs: {
lang: 'en'
},
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: '' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
},
css: [
],
plugins: [
],
components: true,
buildModules: [
'#nuxtjs/tailwindcss',
],
modules: [
],
router: {
base: '/prod'
},
build: {
}
}
Are you passing it as
<p>Path: {{ $route.path }}</p>
<NuxtLink to="/">Back to Mountains</NuxtLink>
if Yes then it should work else try going with redirect('/{stage}/_nuxt')
for an if statement put this inside else , I think it should work.
Related
UPDATE: I installed Strapi version 3.6.3 and it works well
Strapi - Clouinary connection do not work for me. So I'm uploading pictures to Stapi, but they don't appear in Clouinary.
In config folder I created file plugins.js with following content:
module.exports = ({
env
}) => ({
// ...
upload: {
provider: 'cloudinary',
providerOptions: {
cloud_name: env('CLOUDINARY_NAME'),
api_key: env('CLOUDINARY_KEY'),
api_secret: env('CLOUDINARY_SECRET'),
},
},
// ...
});
I have installed npm i strapi-provider-upload-cloudinary
then changed file .env to
PORT=1337
CLOUDINARY_NAME="***"
CLOUDINARY_KEY="***"
CLOUDINARY_SECRET="***"```
Actually automatically following code added automatically:
```JWT_SECRET=*********
API_TOKEN_SALT=*********
JWT_SECRET=*********
What could be a problem?
should CLOUDINARY_SECRET be in "quotes"? or in 'quotes' or without quotes?
Terminal output after adding image is following:
http://localhost:1337
[2021-12-07 02:10:14.702] http: POST /upload (261 ms) 200
[2021-12-07 02:10:14.744] http: GET /upload/files?sort=updatedAt:DESC&page=1&pageSize=10 (24 ms) 200
[2021-12-07 02:10:14.758] http: GET /uploads/thumbnail_Screenshot_2021_11_26_130226_11a95e81ea.png?width=1504&height=1258 (4 ms) 200
All permissions seems to be set...
Also created extentions/upload/config/setting.json with the following content:
"provider": "cloudinary",
"providerOptions": { "cloud_name":"devert0mt",
"api_key": "***",
"api_secret":"***"
}
}{
"provider": "cloudinary",
"providerOptions": { "cloud_name":"devert0mt",
"api_key": "***",
"api_secret":"***"
}
}```
If you want to use the latest version of Strapi, v.4 and above, you need to change strapi provider package to this one:
npm install #strapi/provider-upload-cloudinary --save
Then, you need to update your plugins.js file in config/plugins.js to the following ( Be aware that it has a slightly different structure than the previous package - everything is placed in config object, instead of upload like it was on a previous version):
module.exports = ({ env }) => ({
// ...
upload: {
config: {
provider: 'cloudinary',
providerOptions: {
cloud_name: env('CLOUDINARY_NAME'),
api_key: env('CLOUDINARY_KEY'),
api_secret: env('CLOUDINARY_SECRET'),
},
actionOptions: {
upload: {},
delete: {},
},
},
},
// ...
});
Also, if you are having issues with properly rendering your images on your Strapi dashboard you can update middlewares.js in config/middlewares.js:
Instead of 'strapi::security' in module.exports, paste this:
// ...
{
name: 'strapi::security',
config: {
contentSecurityPolicy: {
useDefaults: true,
directives: {
'connect-src': ["'self'", 'https:'],
'img-src': ["'self'", 'data:', 'blob:', 'res.cloudinary.com'],
'media-src': ["'self'", 'data:', 'blob:', 'res.cloudinary.com'],
upgradeInsecureRequests: null,
},
},
},
},
// ...
I have been trying to get Rewrites working in NextJS for my API Paths. It was to avoid CORS issues.
I followed the solution from: NextJs CORS issue.
It is working on localhost but does not work in a production environment (I was deploying on Vercel itself).
I basically tried with all the types of rewrites:
async rewrites() {
return {
beforeFiles: [
{
source: "/api/:path*",
destination: `https://example.com/api/v1/:path*`,
basePath: false,
},
],
afterFiles: [
{
source: "/api/:path*",
destination: `https://example.com/api/v1/:path*`,
basePath: false,
},
],
fallback: [
{
source: "/api/:path*",
destination: `https://example.com/api/v1/:path*`,
basePath: false,
},
],
};
},
This rewrite works on localhost but on production, the rewrite stops working and the API calls go to /api/:path* itself.
The /api path is reserved for their Serverless Functions. Changing the source path to something else would resolve the issue.
I use Strapi with Nuxt and i18n to produce a static site in English and Danish.
The site should be able to produce URLs like these:
mysite.com/
mysite.com/da
mysite.com/news/a-story
mysite.com/da/nyheder/en-historie
mysite.com/cases/a-case
mysite.com/da/case/en-case
I have a pages folder structure like this
_cases
_slug.vue <-- for case pages
_news
_slug.vue <-- for news pages
_slug.vue <-- for other pages
index.vue <-- for my frontpage
I use the following code to list links for nice URLs that renders just fine
h2 case
router-link(:to="localePath({ name: 'cases-slug', params: { cases: $t('slugs.cases'), slug: aCasePage.slug }})") {{aCasePage.title}}
h2 news
router-link(:to="localePath({ name: 'news-slug', params: { news: $t('slugs.news'), slug: aNewsPage.slug }})") {{aNewsPage.title}}
The problem is, that no matter if I click and go to a news page or a case page, I get served the same _cases -> _slug.vue component.
Looking into the .nuxt/router.js file, the routes seems to be generated correct:
routes: [{
path: "/da",
component: _1ea75fec,
name: "index___da"
}, {
path: "/da/:slug",
component: _2214a27c,
name: "slug___da"
}, {
path: "/da/:cases/:slug?",
component: _3a25cd77,
name: "cases-slug___da"
}, {
path: "/da/:news/:slug?",
component: _3988eeb6,
name: "news-slug___da"
}, {
path: "/",
component: _1ea75fec,
name: "index___en"
}, {
path: "/:slug",
component: _2214a27c,
name: "slug___en"
}, {
path: "/:cases/:slug?",
component: _3a25cd77,
name: "cases-slug___en"
}, {
path: "/:news/:slug?",
component: _3988eeb6,
name: "news-slug___en"
}],
How can I avoid Nuxt mixing up these routes? and the page Vue-components matched to them?
can you share you solution for the _slug pages data fetching ?
I am using findOne (slug,_locale:i18n.locale) from strapi .it's not working
so still hold on this issue
I followed the instructions to use Sass in my Docusaurus v2 project, but I get the following error when I run yarn start:
Error: Cannot find module 'docusaurus-plugin-sass'
My config file is straight out of the box:
module.exports = {
title: '...',
tagline: '...',
url: '...',
baseUrl: '/',
favicon: 'img/favicon.ico',
organizationName: '...', // Usually your GitHub org/user name.
projectName: '...', // Usually your repo name.
themeConfig: {
navbar: {...},
footer: {...},
},
presets: [
[
'#docusaurus/preset-classic',
{
docs: {...},
blog: {...},
theme: {
customCss: require.resolve('./src/scss/index.scss'),
},
},
],
],
plugins: ['docusaurus-plugin-sass'],
};
Is this a bug or am I missing something?
Few things to check
Did you add docusaurus-plugin-sass to your package.json?
If you're using alpha.56, take note of the following change - https://github.com/facebook/docusaurus/releases/tag/v2.0.0-alpha.56
If you refer to modules (plugins) in your config file in a string form, you will need to replace them with require.resolve calls, for example:
- plugins: ['#docusaurus/plugin-google-analytics']
+ plugins: [require.resolve('#docusaurus/plugin-google-analytics')]
Is it possible to write unit tests for VueJs if you are using Laravel's Elixir for your webpack configuration?
VueJs 2x has a very simple example for a component test: Vue Guide Unit testing
<template>
<span>{{ message }}</span>
</template>
<script>
export default {
data () {
return {
message: 'hello!'
}
},
created () {
this.message = 'bye!'
}
}
</script>
and then...
// Import Vue and the component being tested
import Vue from 'vue'
import MyComponent from 'path/to/MyComponent.vue'
describe('MyComponent', () => {
it('has a created hook', () => {
expect(typeof MyComponent.created).toBe('function')
})
it ...etc
})
and gives an example of a karma conf file here: https://github.com/vuejs-templates
But the Karma configuration file requires a webpack configuration file
webpack: webpackConfig,
The only problem is the Laravel's Elixir is creating the webpack configuration so it can't be included.
I have tried creating another webpack configuration file based on the example from https://github.com/vuejs-templates/webpack.
Something like this:
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'build.js'
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
// Since sass-loader (weirdly) has SCSS as its default parse mode, we map
// the "scss" and "sass" values for the lang attribute to the right configs here.
// other preprocessors should work out of the box, no loader config like this necessary.
'scss': 'vue-style-loader!css-loader!sass-loader',
'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax'
}
// other vue-loader options go here
}
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
}
]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
devServer: {
historyApiFallback: true,
noInfo: true
},
performance: {
hints: false
},
devtool: '#eval-source-map'
}
and included it like...
// Karma configuration
// Generated on Wed Mar 15 2017 09:47:48 GMT-0500 (CDT)
var webpackConf = require('./karma.webpack.config.js');
delete webpackConf.entry;
module.exports = function(config) {
config.set({
webpack: webpackConf, // Pass your webpack.config.js file's content
webpackMiddleware: {
noInfo: true,
stats: 'errors-only'
},
But I am getting errors that seem to indicate that webpack isn't doing anything.
ERROR in ./resources/assets/js/components/test.vue
Module parse failed: /var/www/test/resources/assets/js/components/test.vue Unexpected token (1:0)
You may need an appropriate loader to handle this file type.
| <template>
| <span >{{test}}</span>
| </template>
Ok, I got this to work. Couple of things that might help.
I was originally running gulp, and trying to run tests in my vagrant box, to try to match the server configuration. I think that makes it much harder to find examples and answers on the internet.
Ok, so the main problem I was having is that webpack wasn't processing my components included in my test files. I copied the webpack config out of the laravel-elixir-vue-2/index.js node module directly into the Karma configuration file and it started working.
The key is that karma-webpack plugin needs both the resolve and module loader configuration settings (resolve with alias and extensions) for it to work.
Hope this helps someone.
karma.conf.js:
module.exports = function (config) {
config.set({
// to run in additional browsers:
// 1. install corresponding karma launcher
// http://karma-runner.github.io/0.13/config/browsers.html
// 2. add it to the `browsers` array below.
browsers: ['Chrome'],
frameworks: ['jasmine'],
files: ['./index.js'],
preprocessors: {
'./index.js': ['webpack']
},
webpack: {
resolve: {
alias: {
vue: 'vue/dist/vue.common.js'
},
extensions: ['.js', '.vue']
},
vue: {
buble: {
objectAssign: 'Object.assign'
}
},
module: {
loaders: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'file-loader',
query: {
limit: 10000,
name: '../img/[name].[hash:7].[ext]'
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 10000,
name: '../fonts/[name].[hash:7].[ext]'
}
}
]
}
},
webpackMiddleware: {
noInfo: true,
},
coverageReporter: {
dir: './coverage',
reporters: [
{ type: 'lcov', subdir: '.' },
{ type: 'text-summary' },
]
},
});
};
I ran into the exact same problem. The accepted answer did not fully work for me. The following solved my issue:
Install relevant loaders for webpack:
npm install --save-dev vue-loader file-loader url-loader
Create webpack config file (note the format). The accepted answer produced errors citing invalid format of the webpack.config.js file. At least with me it did.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.vue$/,
use: [
{ loader: 'vue-loader' }
]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
use: [
{
loader: 'file-loader',
query: {
limit: 10000,
name: '../img/[name].[hash:7].[ext]'
}
}
]
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
use: [
{
loader: 'url-loader',
query: {
limit: 10000,
name: '../fonts/[name].[hash:7].[ext]'
}
}
]
}
]
}
}
karma.conf.js
// Karma configuration
var webpackConf = require('./webpack.config.js');
delete webpackConf.entry
module.exports = function(config) {
config.set({
frameworks: ['jasmine'],
port: 9876, // web server port
colors: true,
logLevel: config.LOG_INFO,
reporters: ['progress'], // dots, progress
autoWatch: true, // enable / disable watching files & then run tests
browsers: ['Chrome'], //'PhantomJS', 'Firefox',
singleRun: true, // if true, Karma captures browsers, runs the tests and exits
concurrency: Infinity, // how many browser should be started simultaneous
webpack: webpackConf, // Pass your webpack.config.js file's content
webpackMiddleware: {
noInfo: true,
stats: 'errors-only'
},
/**
* base path that will be used to resolve all patterns (eg. files, exclude)
* This should be your JS Folder where all source javascript
* files are located.
*/
basePath: './resources/assets/js/',
/**
* list of files / patterns to load in the browser
* The pattern just says load all files within a
* tests directory including subdirectories
**/
files: [
{pattern: 'tests/*.js', watched: false},
{pattern: 'tests/**/*.js', watched: false}
],
// list of files to exclude
exclude: [
],
/**
* pre-process matching files before serving them to the browser
* Add your App entry point as well as your Tests files which should be
* stored under the tests directory in your basePath also this expects
* you to save your tests with a .spec.js file extension. This assumes we
* are writing in ES6 and would run our file through babel before webpack.
*/
preprocessors: {
'app.js': ['webpack', 'babel'],
'tests/**/*.spec.js': ['babel', 'webpack']
},
})
}
Then run karma start and everything should work.