Nuxt js dynamic route not work after generate - vue.js

in my project i am using nuxt js. I have a route looks like
service/:slug
After build and generate my all route works perfectly.Bellow code I use to generate dynamic route on generate
generate: {
routes(callback) {
axios
.get('url')
.then(res => {
const routes = res.data.data.map(service => {
return '/services/' + service.slug
})
callback(null, routes)
})
.catch(callback)
axios
.get('https://url')
.then(res => {
const routes = res.data.data.map(offer => {
return '/campaigns/' + offer.slug
})
callback(null, routes)
})
.catch(callback)
}
}
But problem occurs when I create another new item from admin panel after build and generate.
seems I have three route when I run nuxt generate
service/cash
service/profit
now after host my dist folder in server then I hit www.url/service/cash and its work perfectly.
Now I create a new service item in admin panel called send-money
Then when I hit on browser using www.url/service/send-money
Its not working and get 404.
now I cant understand how can I solve this situation.

When using SSG nuxt only generates the available pages in your project. This is how SSG works. Therefore, you need to create a custom script in your server to run ‍yarn build && yarn generate command after creating new page.
For example, let us assume you are creating a blog. When you use ‍‍‍yarn generate, nuxt generates the posts fetched from the database at that specific time and moves them inside dist folder. Therefore, you need to attach a custom script -which you need to somehow create in the backend- to run yarn build && yarn generate after creation of a new post.

If you're using something like firebase static hosting...you only need to make sure you have wildcard rewrites rules in place to prevent 404 errors. In this case this is what I have in my firebase.json files.
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]

Related

Fetch data from local JSON file with Nuxt Pinia

Is it possible to fetch a local .json. file using fetch()? I originally used the import method but the site's data doesn't get updated unless the page gets reloaded.
I tried doing this but it's not working:
stores/characters.ts
export const useCharactersStore = defineStore("characters", {
state: () => ({
characters: [],
}),
getters: {
getCharacters: (state) => {
return state.characters;
},
},
actions: {
fetchCharacters() {
fetch("../data.json")
.then((response) => response.json())
.then((data) => {
this.characters = data.characters;
});
},
},
});
app.vue
import { useCharactersStore } from "~/stores/characters";
const store = useCharactersStore();
onMounted(() => {
store.fetchCharacters();
});
Any help would be appreciated.
maybe a bit late but I have encountered the same problem migration from Nuxt 2 to Nuxt 3.
I'm certainly no expert on this, so if anyone finds a better way or if I'm totally wrong please let me know !
Whenever you import a json file in vue code they are imported as a module, that get's embedded within the code compilation on build (Vue Docs). Tu use json as a external file you need to place your json within the /public directory and use axios or fetch to load the file with a lifecyle hook.
This could be mounted() for options api or beforeMount()/onMounted() with composition api.
However some important annotations for this method.
If the json file you want to use in your app is not reactive, i.e. won't change, you should place this in the static folder of the nuxt app.
In your example you fetch '../data/...', this would imply the server knows the domain to look for. It can't call the route like this, you would have to give the full url if you put your json file in the static folder.
Set the baseUrl in the of your nuxt.config.ts, see docs for specifications.
Then you can access the static folder with your .env variables
--> $fe
Then in you data script you can access your json file
async getJson(some parameters){
const data = $fetch('your domain with the runtimeConfig composable').then((data)=>{ console.log(data)});
Sidenote you can also load the file from the server-side using fs.readFile
read more about this in this awesome post here

Nuxt static - API call

I'm having trouble dealing with API calls from NUXT static app.
Locally with yarn dev i can get it to work, but when i deploy it (tried with netlify and AWS S3 following this tutorial), i get No 'Access-Control-Allow-Origin' header is present on the requested resource error when calling external API, and the dev tools shows the API call.
But as stated in the official NUXT docs "All calls to APIs will be made and cached in a folder called static inside your generated content so that no calls to your API need to be made on client side navigation.(link)", the API call shouldn't be visible in the dev tools, but i can see it (even in the dev env).
I call the API inside a mixin, just like that:
export const actions = {
async fetchUpcomingGames({ commit }) {
const response = await this.$axios.get('https://api.pandascore.co/matches/upcoming?sort=&page=number=1&size=100&token=MY_TOKEN')
commit('setUpcomingGames', response.data)
}
Build settings on Netlify is like the NUXT docs:
Build command: yarn generate
Publish directory: dist
In nuxt.config i have the settings created by yarn create nuxt-app, wchich is bassicaly:
target: 'static',
modules: [
'#nuxtjs/axios',
],
axios: {
baseURL: '/',
}
It is a simple app with only one layout and one page, not a big deal. What am i missing ?

Next JS route is not resolving in production build

I have a following route pattern in the custom server of NextJs project. Everything works fine in the development. But in production build the route is not recognised and goes to 404 page.
Routes
{ name: 'business-with-key', pattern: '/:keyword-in-:location', page: 'packages/index' },
In the development I can get both the params with this code.
packages/index.tsx
export const getServerSideProps: any = async (ctx: NextPageContext) => {
const { query, req } = ctx;
const { keyword, location } = query;
But when I build the project in docker and run it, the route http://localhost:3000/photo-in-london reaches 404 when deep linked. Works fine with SPA navigation.
Any idea what I'm doing wrong here?

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.

Nuxt - How can I run a code in client-side after server-side-rendering?

I created a plugin injecting a noty (https://ned.im/noty/#/) so I can use it globally, it looks like this:
export default ({ app }, inject) => {
const notify = function (options = {}) {
if (process.client) {
new Noty(options).show();
}
}
app.$notify = notify;
inject('notify', notify);
}
This plugin shows a noty only on the client-side. On the server-side a noty does not appear, cause it can be displayed only in browser.
I have a page with product details and I am receiving data in asyncData method. When the product was not found I would like to show a noty with proper message and redirect user to a product list page. When I change a route in client-side everything works awesome. However on the first page load (eg. I change an url manually in the browser) which happens on the server-side a noty does not appear, only a redirect works.
My question is: how to show a noty in this case? How to create a noty in the browser after SSR or what is the best other solution to my problem?
Is there any way to run some code after client-side is already rendered (after server-side-rendering)?
You could just disable ssr for that plugin.
plugins: [
...,
{ src: '~plugins/yourplugin.js', ssr: false }
]
Okay, I found a module for that: https://github.com/potato4d/nuxt-client-init-module
it's not possible right know (nuxt <= 2.14.0 when i answering)
but you can combine client plugin and client middleware to achieve that
please take a look at this link:
https://github.com/nuxt/nuxt.js/issues/2653#issuecomment-390588837