Open owengot opened 5 years ago
plugins/vue-masonry-css.js
import Vue from 'vue'
import VueMasonry from 'vue-masonry-css'
Vue.use(VueMasonry);
nuxt.config.js
plugins: [
{ src: '~/plugins/vue-masonry-css', ssr: false }
]
components/gallery.vue
<template lang="pug">
div
no-ssr
masonry(:cols='3', :gutter='30')
div(v-for='(item, index) in items', :key='index') Item: {{index + 1}}
</template>
I tried this approach but still get: Unknown custom element: <masonry> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
Any idea what I'm doing wrong? I have the same setup as the answer by @danchristian
@danchristian this is NOT SSR.
This approach completely removes all contents from server-side-render, and leaves rendering to client. It means no performance advantages and no crawler would be able to read site data
As a workaround for SSR, you might want to duplicate the data in a hidden div.
In your gallery.vue use<client-only> <masonry ... > </client-only>
, "no-ssr" is deprecated and should not be used anymore. I realize this is over a year old and I'm just pointing out the new way of blocking SSR. It worked fine in my nuxt app using the configuration danchristian provided, the only difference is I'm loading the masonry element inside a 'client-only' element.
In your gallery.vue use
<client-only> <masonry ... > </client-only>
, "no-ssr" is deprecated and should not be used anymore. I realize this is over a year old and I'm just pointing out the new way of blocking SSR. It worked fine in my nuxt app using the configuration danchristian provided, the only difference is I'm loading the masonry element inside a 'client-only' element.
Thanks, This was perfect.
Even when used with
Even when used with it produces hydration issues on initial page rendering
I don't get this error when using <client-only>
, make sure you have your Nuxt configuration correctly load the component as a client-only plugin. The issue at hand here was the inability to load masonry at all due to an incorrect Nuxt configuration. If the original post had a repository with the Nuxt app that could repeat the issue we could likely solve it.
The server mismatch you're getting is likely due to a misconfiguration in your Nuxt app. I posted my Nuxt configuration below which works perfectly, make sure in the nuxt.config.js the plugin has the ssr: false
and the source file ~/plugins/vue-masonry.js
exists and contains the import statements to load the Masonry component. Then when you use it in your component called gallery.vue in this case, make sure to wrap the masonry element in the <client-only>
element. Also ensure you're following the syntactic rules of HTML markup as the error states inside your masonry component.
I feel that this is getting a bit off topic and the issue should probably be closed if it can be stated why this issue is not a vue-masonry-css issue but more of an issue loading it in a different framework than just plain Vue. I am under the impression that the masonry component itself works fine with Nuxt apps as a client-only plug-in.
nuxt.config.js
plugins: [
{ src: '~/plugins/vue-masonry.js', ssr: false }
],
~/plugins/vue-masonry.js
import Vue from 'vue'
import VueMasonry from 'vue-masonry-css'
Vue.use(VueMasonry)
components/gallery.vue
<client-only>
<masonry
:key="view"
ref="masonry"
class="masonry-element"
...
>
</client-only>
@ikluhsman what do you mean by misconfiguration? When you put something client only that means that on initial render you most definitely creating a hydration issues, because your client VDOM is different from SSR DOM, it's just how Nuxt works.
In the meanwhile, you can rely on https://github.com/ymmooot/nuxt-jsonld to keep using SEO features on SSR.
@the94air how is it related to what we discuss here?
@AndrewBogdanovTSS I thought that's what everyone is trying to deal with, not being able to show the data to crawlers due to no SSR support 🥴
@AndrewBogdanovTSS I thought that's what everyone is trying to deal with, not being able to show the data to crawlers due to no SSR support 🥴
No, it's not an issue here. The problem is that component doesn't work at all if not used as client-only and even if used - it creates hydration issues that can lead to a complete page brake down where component is used
@ikluhsman what do you mean by misconfiguration? When you put something client only that means that on initial render you most definitely creating a hydration issues, because your client VDOM is different from SSR DOM, it's just how Nuxt works.
Yes you are correct. My comment about misconfiguration was a bias from an unrelated issue causing problems in the last SSR app I was working on. Nonetheless, it seems to work on static generated pages without SSR, but again like you said, client-only is not the issue at hand. My apologies for the unhelpful comments. If I am able to assist the problem in my SSR apps I'll report back.
The reason that causes SSR issue here is the fact that different number of columns are used on different resolutions. Since in SSR mode there is no bulletproof way to detect screen resolution of the user device mobile brakepoint is loaded by default but once client side kicks in number of columns is changed which creates hydration issue. Possible solution would be detecting user agent on the server, this could give at least approximate result which is enough in 99% of the cases. @ikluhsman the fact that you might not had this issue is probably because you always used same amount of columns for each resolution
Hello, I am trying to find a masonry layout package that works with SSR. Can someone update me on whether this library works in Nuxt's SSR mode? If not, anyone have other suggestions. I checked out vue-masonry-wall but that one doesn't seem to work with SSR any longer. Thanks.
@dosstx if you will find one - let me know. I guess in the future we could write a wrapper solution around this library that would detect support for grid-template-rows: masonry
that would work perfectly on SSR, you can read more about it here:
https://www.smashingmagazine.com/native-css-masonry-layout-css-grid/
but unfortunately as of now, it's not supported in any modern browser
https://caniuse.com/?search=grid-template-rows%3A%20masonry
until then we are stuck with SSR issues. Frankly speaking, I don't think that any lib that is based on flexbox columns will be able to handle it gracefully and handling it any other way, like absolutely positioning every item and recalculating positions on browser resize will give you a very poor performance so I would try to stay away from such options as much as possible
@AndrewBogdanovTSS Thanks for the update, Andrew!
The only thing I've been able to do is use Bootstrap and then write some logic to chunk the fetched data array into 3 columns. This gives me a masonry layout that works even with SSR (see concept screenshot below -- this is also what it looks like with JavaScript turned off).
The cards are also rendered horizontally which is good for a natural left-to-right scan (latest cards are first and older cards are last).
Unfortunately, two problems with this approach:
1.) If you plan to dynamically sort the cards (ie, sort by most views
, sort by most comments
, etc) the new ordering will not be in order (though, I haven't tested it yet)
2.) In mobile/single column breakpoint, the ordering is not chronological. Though, for this, I think we can use client hints and fetch accordingly...though I haven't tried that yet.
@dosstx the main problem with SSR in my use case was a responsive behavior. Since we can't reliably detect screen dimensions during SSR a fallback to mobile layout is done which creates hydration issues on desktop due to different amount of columns per brakepoint.
Just found this ported version of vue-masonry-wall. It works for me...even with SSR!
https://vue2-masonry-wall.yeger.eu/
And my sandbox:
https://codesandbox.io/s/yeger-masonry-vue2-v03xv?file=/pages/index.vue
No hydration issues, either.
@dosstx thanks, I will try that
Has anyone tried using this with Nuxt.js? I'm trying to use it as a plugin but get the following message: