What is the difference between 'ssr:false' vs 'target:static' in NuxtJS? - vue.js

To generate a static site using NuxtJS, it seems there are 2 options to set: ssr:false and target:static inside the NuxtJS config file (nuxt.config.js) which practically do the sme thing? Why both of them exist if they do the same thing? or is there any difference between the two options.

ssr: false is used if you want to have only an SPA.
On the other hand, target: 'static' is used if you want to have SSG, rather than regular SSR (with taget: 'server').
It means that you could have a mix of:
ssr: true + 'static' aka SSG
ssr: true + 'server' aka SSR
ssr: false + 'static' aka SPA
Feel free to make a search on Stackoverflow to have more details.
To answer the question, static can be SSG or SPA, but the second one doesn't have all the SEO benefits etc, it's pretty much a regular Vue app (and you're loosing quite some benefits of Nuxt).

Related

disable nuxt code splitting. how to pack everything into a single file

I have a simple vue / nuxt project that I would like to serve from AWS lambda.
For this, I'd like to group everything into a single file.
I see that Nuxt is splitting the files in order to only load what matters at a given time, but the app is a single page, is for internal use and loading time / memory usage is completely irrelevant.
My question is 2 fold:
how can I disable the file splitting
is there a way to pack everything into a single index.html file? I didn't find a solution on the web because the moment I start to research solutions, I keep finding posts about SSR which is also totally irrelevant to my case.
For the split part, this one with all set to false should be enough: https://nuxtjs.org/docs/2.x/configuration-glossary/configuration-build#splitchunks
Like this
export default {
build: {
splitChunks: {
layouts: false,
pages: false,
commons: false
}
}
}
This one should also help: https://github.com/nuxt/nuxt.js/issues/2363
You also can have the whole control of the webpack config here: https://nuxtjs.org/docs/2.x/configuration-glossary/configuration-build#optimization
As for hosting on Lambda, you can check those 2 articles:
https://www.serverless.com/examples/aws-node-vue-nuxt-ssr
https://medium.com/#fernalvarez/serverless-side-rendering-with-aws-lambda-nuxtjs-b94d15782af5

NuxtJS Content Security Policy

Unable to apply a content security policy without including unsafe-inline for scripts and styles.
NuxtJS generates both inline styles and scripts upon build.
As my application is static, NuxtJS default configuration for this does not work as it requires Server side rendering to achieve this. I haven't been able to find a way to inject a nonce into the build process to solve this issue.
My current setup is to apply Security HTTP Headers to the domain is using a cloudflare worker which does not touch the application. Therefore I am looking for options how to integrate this between the application and edge worker https://scotthelme.co.uk/csp-nonces-the-easy-way-with-cloudflare-workers/
Came across couple of injecting methods using middleware while browsing nuxtjs github issues which I can't get to work.
Has anyone found a solution for generating a policy which does not include unsafe-inline, either directly in the application or externally?
NuxtJS generates both inline styles and scripts upon build. ... I haven't been able to find a way to inject a nonce into the build process to solve this issue
From the point of view of the CSP
there are 3 types inline scripts and only 1 of them may be allowed using 'nonce-value'
there are 3 types on inline styles (including JS call of .setAttribute() function - yeah it's requires 'unsafe-inline' in style-src too), and only 1 of them may be allowed using 'nonce-value'.
Therefore, in an abstract form, your task is not solvable, you need specifics.
Assuming you are only using <script>...</script> and <style>...</style> constructs (these may be allowed using 'nonce-value') you have 3 options:
use 'nonce-value'
use 'hash-value'
place script/style into external file and use 'self'
In case of usage document.createElement('style'), opt 1 is preferable you just set style.nonce = 'generated_base64_value' attribute. Because to calculate 'hash-value' is not easy in this case.
In case of usage <script>...</script> and <style>...</style> much easier to calculate hashes or move all to external file (opts 2, 3). To use cloudflare workers is complicate the code unnecessarily in this case.
Some middleware generates a lot of separate <style>.red {color:red;}</style>, <style>.r_padd {padding-right:20px;}</style>, etc. It is a headache for opts 1, 2, but easy solvable via opt 3.
If you use third-party scripts, for example Google Tag Manager, there is no way to get rid of 'unsafe-inline' scripts, and from 'unsafe-eval' too in some cases.
PS: There is no universal way. And not knowing what is under the hood of your car, it is difficult to give advice on how to afterburner it.

svelte + express (without sapper) - how to send props/communicate with the server?

I am coding a little website to be my homepage.
So far I managed to do what I wanted with express and handlebars templates but I am doing this website to test my boundaries, and I lack using a frontend framework and working with web components.
so for the sake of challenge and learning, I settled on svelte
which is not exactly a framework, I read, but is a delight to write with and seems very promising on the performance side.
The problem is I want to keep the hand on my website, and sapper, the full framework that comes with svelte, is a bit too much of a black box for me.
(you put this file here and that file there,
compile with this complex configuration you shouldn't touch
and BOOM you got routes)
What I would like is to use express to manage the routes and then render the svelte app, either with a different page/app for a route, or the same app with different variables.
Could anybody point me in the right direction?
I considered using sessions or a socket, but I have no idea of how to listen to this client-side and the documentation/articles about svelte are sparse and all talk about sapper.
here are a few lines of code I wrote in a test app. I know it's not the way you do it but it was for curiosity's sake
// --------------server.js
// ...
app.set('view engine', 'hbs')
app.set('views', path.join(__dirname, '../views'))
// Using a view engine on TOP of svelte
// is certainly a bad choice
app.use(express.static('app/public'))
// to make the svelte compiled .js and .css available
app.get('/test', (req, res) => {
res.render('home', {user:true})
// I tried to send props like this
// it did not get the props in svelte,
// but what I found is that svelte ADDS itself to the page
// and does not remove the HBS code, event though it is in the target container
})
edit
I will finally use sapper, thank you for the advices...
I really would like them to implement some sort of svelte middleware that allows to render/serve pages individually (once they are build of course)
If you do it like that, splitting your web application into several independent svelte apps that are served from express, then you need to keep the (web-)application wide state on the backend or keep it in the local storage on the browser. You can't use the states provided by sveltes store (writeable, etc), because that's in-memory and destroyed whenever you navigate to a new page (via express).
If sapper is to much magic but you want to keep running a single-page-app, have a look at svelte-spa-router. That isn't configuration based.

Assign/add mixin or sub-component at runtime?

Can I dynamically add a mixin? I think I read that runtime insertion of mixins is not supported and will never be. Is the below runtime insertion possible?
My usecase is; all our pages are stored in a database, each page standard properties like; title, content and template. We have components for each template. Each template component displays the title and content differently. So I need to build the routes and say this page uses this (template) component. Maybe I can use sub-components to achieve this? Can I dynamically add sub-components at runtime?
The easiest solution is to do the following:
Router:
// myPages retrieved by REST call
const routes = _.map(myPages, page => {
return {
path: `/${page.url}`,
name: page.name,
component: DefaultPage // make all pages use DefaultPage component
}
});
DefaultPage.vue
<template>
</template>
<script>
import mixins from './mixins';
export default {
mixins: [mixins.Base]
beforeMount() {
// I dont think this is possible?
let templateMixin = mixins[ this.page.template ]
this.mixins.push( templateMixin );
}
}
</script>
Maybe its possible to assign a sub-component at runtime?
<template>
// Somehow call the sub-component (template)?
<template></template>
</template>
<script>
import templates from './templates';
export default {
components: {},
beforeMount() {
// Is this possible?
let templateCmp = templates[ this.page.template ]
this.components = {
templateCmp
}
}
}
</script>
Unfortunately there is a lot of misinformation on the web stating that "because of userland perils, it's not safe or secure to load dynamic or "runtime" components", and that doing so is "a security risk".
This stems from the reasoning that Vue uses the eval statement when compiling components. However, so does React and Angular. There is in fact no way to compile components without this. while eval is a sharp knife, so is any JavaScript. Saying that a sharp knife is insecure is false as long as you keep that sharp knife itself secure.
The notion that runtime components is insecure is utterly and completely false. There are tons of officially supported ways to do this if you control the source. In fact, there is even an officially Vue supported "userland" method to load dynamic/async components even if you don't control the source(!!)
Async components
Probably the easiest way to load a page from a database (which itself may have it's own sub-components, mixins and dependencies), is with async components.
This is an official part of Vue and I've used it in dozens of production apps. It works exactly like expected; nothing is invoked by your application until all the conditions are met, and when the load conditions are met, you are free to obtain the component however you see fit.
Note: You must control the source of these components, or XSS injection and other hacking is possible.
If you're using webpack, it's easy to get all the components dependencies into a single file. In the above URL are specific how-to articles including a video tutorial of how to produce a single js file for your pages dependencies that aren't part of your main application.
One caveat for loading multiple sub components this way is you may overlap/repeat loading (i.e. page A may load 5 sub components that no other static page loads, and page B may load 5 sub components, 3 of which are shared with page A, and 2 of which are specific to page B). Caveats like these can mess up your optimization techniques if you don't think them through. This can be unavoidable and fine, and still much faster than loading the entire app at once though.
Async components in userland
If you only want to load custom templates from a database (i.e. if you don't want to allow users to load their own custom components, mixins, filters, directives, etc), with each template, then you are in luck; Vue even has official support for async templates that are locked-down to only allowing template changes. This is enough to offer your component builders scaffolding for creating an app, but prevents them from executing arbitrary JavaScript code (this method won't let them setup a data section, or hook into the component lifecycle for example).
v-runtime-template is officially recognized by the Vue.js team as the official method for creating userland-safe Vue templates.
I've used v-runtime-template in platforms used by some of the biggest names in the industry across tens of millions of users without a single security breach, because this method only exposes the components you say are OK.
Further template lockdown using JSON schemas
If you need only form generation, or you can simplify your components further, and you only need to reason about data in simple ways like queries (i.e. if you're building a survey generator, or an analytics or other widget dashboard), you can build components out of JSON Schemas using vue-form-json-schema. This method takes 2 schemas: one for your data, and one for your form. The parent component you load specifies all the components that are accessible to the schema, so you must whitelist components that userland has access to, further, the forms cannot run arbitrary JavaScript, they can only call functions that you make available in the parent component, which are your JavaScript whitelist.
Userland-Safe Queries on arbitrary data
You can let users query specific JSON objects for use in completely-safe userland queries that can be provided by the public using JSONata. Developed by IBM, JSONata is a way to safely query and, with the exposure of a few functions, allows your users to even manipulate data in verified-safe ways.
Although JSONata is logically proven to be safe in unserland, it is also Turing-complete without functions, meaning your users can manipulate the Schema provided data by outputting new data that can technically do anything; i.e. your users can create Doom 3 using JSONata queries. People have made games like Pong and other interesting things out of JSONata.
JSONata's power cannot be overstated. It powers the magic behind nearly all no-code/low-code platforms like the open source Node-RED, and is behind many other proprietary no-code/low-code platforms that are closed source, including Google, Microsoft, Amazon and IBM platforms.
They use JSONata to translate data schemas between platforms, and whenever business logic is needed on data manipulation, and the manipulation must be left in user-land (i.e. an app that needs to manipulate data, but you want to run that app on your platform and not have to worry about QA or people being able to hack or write a nefarious app that breaks into your platform).

How to send configuration from ExpressJS to Aurelia

I am building a website based on https://github.com/Vheissu/aurelia-starter-node. It will have some backend logic in the /api area and there will be also a SPA area handled by Aurelia. I would like to:
read config in express app (https://www.npmjs.com/package/config) using require('config')
use this config on the server (usual stuff)
use a subset of this config on the client (in the Aurelia app)
I know about https://github.com/Vheissu/Aurelia-Configuration but I don't want to maintain two config sets handled by different libraries, dealing with setting the environment in two places etc.
Question: is there a clean way to do what I am looking for?
My thoughts so far:
pass something to aurelia bootstrapping logic, but I can't find any info about this
ugly solution: rendering the config as global variable into index.html (the one which is the master page for the SPA) and read it from Aurelia code, more less like How to pass data from ASP.NET WebForms to Aurelia Global Scope
I ended up keeping the configuration in the server code and rendering only the client part of it to the body of the page like so:
When defining aurelia routes for my app:
let model = {
clientConfig: {
x: 123
}
};
res.render('index.html', model);
And then in view (using ejs templates):
<script>
var config = <%- JSON.stringify(clientConfig) %>;
</script>
For me this feels much cleaner than maintaining the config in two places.