I've seen this elsewhere in other questions, but haven't seen a solution. I'm trying to make a simple GDPR cookie notification that closes on click, using a button. I'm in Universal mode, meaning mounted()
isn't available, so I'm trying to set cookies through Vuex. However, the click event I have bound to the button in my component isn't firing.
Edit: After building a codesandbox version of my app, which worked as it should, I went through and hacked up my Nuxt app until I found what was causing the problem. As it turns out, it was my middleware, and more specifically, the fact that I was using the fs-extra
library to read JSON files. Still not clear on why this is happening, so any suggestions are welcome. The code below includes my middleware.
components/CookieNotice.vue
<template>
<div v-if="cookie != true" class="cookie_notice_wrap">
<div class="cookie_notice">
<p class="notice_message">This site uses cookies for analytics purposes.</p>
<button @click.prevent="dismissNotification" class="notice_dismiss">Close</button>
</div></div>
</template>
<script>
import { mapGetters } from "vuex";
export default {
name: "CookieNotice",
methods: {
dismissNotification: function(e) {
console.log("we clicked?");
document.querySelector(".cookie_notice_wrap").classList.add("hidden_click");
this.store.dispatch("cookieStateChange", true);
}
},
computed: {
...mapGetters(["cookie"]),
}
}
</script>
Actions from store/index.js
export const actions = {
async getPosts({ state, commit, dispatch }) {
if (state.posts.length) {
return
}
try {
await axios.get("/api/json-access");
}
catch (err) {
console.log(err);
}
},
nuxtServerInit({ state, commit, dispatch }, { req }) {
dispatch("getPosts");
const seen = this.$cookies.get("cookie_notice_seen");
if (!seen) {
dispatch("cookieStateChange", false);
}
},
cookieStateChange({state, commit, dispatch}, bool) {
// this does set the cookie correctly, unsure if it will work the same when bound to the button click
commit("updateCookie", bool);
this.$cookies.set("cookie_notice_seen", bool, {
path: "/",
maxAge: 60 * 60 * 24 * 7
});
}
}
~/middleware/api/json-access.js
:
const fse = require('fs-extra');
import axios from 'axios';
const storeLocation = "middleware/full_site.json";
export default async function({ store, route, redirect }) {
const exists = await fse.pathExists(storeLocation);
let posts;
if (!exists) {
await fse.ensureFile(storeLocation);
posts = await postsFromWP();
fse.writeJSON(storeLocation, posts);
}
else {
try {
posts = await fse.readJSON(storeLocation);
}
catch (err) {
console.log(err);
}
}
store.commit("updatePosts", posts);
}
async function postsFromWP() {
const url = ".../example/json/file.json";
const config = { headers: { "Accept": "application/json" }};
let posts = await axios.get(url, config);
posts = posts.data
.filter(el => el.status === "publish")
.map(({ id, slug, title, excerpt, date, tags, content }) => ({
id, slug, title, excerpt, date, tags, content
}));
return posts;
}
I had the middleware configured in nuxt.config.js
via routes -> middleware
before, but currently have it set to go through serverMiddleware
instead, for testing. I also added the action that triggers getting the posts, in case that's also part of it. This has definitely hit on a limit of my Nuxt/Vue understanding - I have no idea why this could be happening, so any wisdom is much appreciated.
If you wind up dealing with something similar, fs
or fs-extra
are your culprits. You can't use file operations on the client side, which is when these middleware actions are happening (I think). The cookie notice only fully worked when I removed the fs-extra
import at the very top of the middleware file.