Nuxt.js: Mismatching childNodes vs. VNodes

Created on 6 Sep 2017  路  22Comments  路  Source: nuxt/nuxt.js

Guys, I'm having a problem and need some help to fix that.

I have a simple HTML structure in my component wich has ul's and li's, it's a carousel. I'm using a carousel plugin called OWL Carousel and this plugin modifies a little bit my HTML structure.

I'm calling the plugin's js file like this:

export default { head: { script: [ { src: '/js/owl2/owl.carousel.min.js' } ] } }

and I'm having this error:

"The client-side rendered virtual DOM tree is not matching server-rendered content."
and a warning
"Mismatching childNodes vs. VNodes:"

Print: http://prntscr.com/ghvp5s

It seems like I can't have a difference betweeen my client side html and what is written on my server side. But most plugins nowdays make modifications on the DOM so it doesn't make sense to have this error.

This question is available on Nuxt.js community (#c1423)
help-wanted

Most helpful comment

Your lib is available only for client-side! So Nuxt tried to renderer from server-side and failed...

You can create a custom plugin with ssr:false option? => https://nuxtjs.org/guide/plugins#client-side-only

// nuxt.config.js
module.exports = {
  plugins: [
    { src: '~plugins/your-owl-plugin.js', ssr: false }
  ],
}

Another way, from your page.vue, you can use the new element (since Nuxt 1.0.0 RC7) <no-ssr>...</no-ssr>
Check this example: https://github.com/nuxt/nuxt.js/blob/dev/examples/no-ssr/pages/index.vue

All 22 comments

Hello there. I'm having the very same problem. I'm not using OWL Carousel, but another plugin that modifies my HTML in the client side. Is there a solution or maybe a markup that indicates that a block of code will be modified after loading?

I'm stuck on the same problem in my vue ssr project and I've been looking for possible workarounds for days.
I hope there is a solution, because it would be sad to restart my project

I have the same problem here.

I have the same problem here. I hope there is a solution.

Your lib is available only for client-side! So Nuxt tried to renderer from server-side and failed...

You can create a custom plugin with ssr:false option? => https://nuxtjs.org/guide/plugins#client-side-only

// nuxt.config.js
module.exports = {
  plugins: [
    { src: '~plugins/your-owl-plugin.js', ssr: false }
  ],
}

Another way, from your page.vue, you can use the new element (since Nuxt 1.0.0 RC7) <no-ssr>...</no-ssr>
Check this example: https://github.com/nuxt/nuxt.js/blob/dev/examples/no-ssr/pages/index.vue

Hello!

I got the same problem here but it's a bit weird. On my local dev machine (Windows 7) all works well and everything macthes (VNodes from SSR and client rendered nodes). But on my Debian server I always get the following:

[Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>. Bailing hydration and performing full client-side render.

As vue gives a list of mismatches, I tried to figure out the real issue.
First: this happens when one element is conditionally rendered with v-if. Server doesn't render it in this case so it's just left out from the server rendered HTML. But the client seems to expect a <!----> there (I don't really know if I interpreted the message in devtools right).

(I'm rendering sr-only text to menu items when they're active)

22:47:13.267 Mismatching childNodes vs. VNodes:  NodeList [ #text "Home " ] Array [ Object, Object ] 1 common.a9c90ef90a2380ee9df6.js:9771:15
  • The first Object is indeed the #text "Home " but the second one would be <!----> as the Object.elm is <!---->

So I think there is an error with the SSR on my Debian machine. I really don't know why this doesn't happen on my dev machine cause I used npm run dev on both machines and everything builds well.

If somebody wants to take a look on the project: https://github.com/jankal/fb-agency
This is the component I was talking about.


I'm using nuxt RC9.

@jankal the same problem, it's sad...

I have the same problem, but on my dev machine. Here is an example of my code. I want to have a random number of divs. In this example it works, but in the Nuxt environment I get the "vue.runtime.esm.js:5613 Mismatching childNodes vs. VNodes" - Error. If I remove "Math.random()" from the methode it works.

I'm also using nuxt RC9 on my Mac with El Capitan.

Should be fixed with the last release, feel free to comment/reopen this issue if the bug persists.

Issue persists, on first-load it's ok now but on refresh of page the error pops up again.

I'm getting the same error message using Bootstrap-vue and Nuxt.js: Mismatching childNodes vs. VNodes:

I have a navbar with a ul and li's. The li's get populated with a v-for loop and the ul displays conditionally with a v-if directive.

The error message in the console is followed by the li's that shouldn't render, since the v-if evaluates to false. Not sure what's causing this. There's also a flicker that I describe in this SO thread.

Having this issue with uikit 3. It seems like every time i refresh it adds 3 VNodes, as it it's not being cleared during page reload. I can navigate to the page just fine but when i refresh it just breaks. Very strange, not sure what i'm missing. Here's a screenshot of the error

Have same error with vuetify with this layout:
https://github.com/vuetifyjs/docs/blob/master/examples/layouts/google-keep.vue

Caused by this line:

Check, does your server (CloudFlare for example) minify/cache the output on the fly.
My problem was there.

Agreed with @yourivandenbrand . This happens when the page is refreshed, not when the routes change.

In my case it disallows me to use some of the external components, as the server always throws "mismatched" error. Would like to see this fixed in near future!

Problem happened for me when I try to select random entries from a GET request.
var randIdx = Math.floor(Math.random() * b.project.length - 3) + 1
// Select 3 projects from each school
var trio = b.project.slice(randIdx, randIdx + 3)

I have thought of using a seed for the generator but don't know how to find this consistent seed between server side and client side...

dont use v-if with nuxt-link , use v-show

Problem occurred when refreshing when the custom component below is present on the page (based on starability.css). I tried <no-ssr> but so far it doesn't solve my problem. No external libraries. Just the component below. Also only occurs on refresh. Not on load.

<template>
  <fieldset class="starability-basic">
    <legend>{{name}}</legend>
    <input type="radio" id="no-rate" class="input-no-rate" name="rating" value="0" checked aria-label="No rating." />
    <input type="radio" id="first-rate1" name="rating" value="1" v-model="rating" disabled/>
    <label for="first-rate1" title="Terrible">1 star</label>
    <input type="radio" id="first-rate2" name="rating" value="2" v-model="rating" disabled/>
    <label for="first-rate2" title="Not good">2 stars</label>
    <input type="radio" id="first-rate3" name="rating" value="3" v-model="rating" disabled/>
    <label for="first-rate3" title="Average">3 stars</label>
    <input type="radio" id="first-rate4" name="rating" value="4" v-model="rating" disabled/>
    <label for="first-rate4" title="Very good">4 stars</label>
    <input type="radio" id="first-rate5" name="rating" value="5" v-model="rating" disabled/>
    <label for="first-rate5" title="Amazing">5 stars</label>
  </fieldset>
</template>

<script>
export default {
  props: {
    name: String,
    rating: Number
  }
}
</script>

<style>
.starability-result {
  position: relative;
  width: 150px;
  height: 30px;
  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAA8CAMAAABGivqtAAAAxlBMVEUAAACZmZn2viTHuJ72viOampqampr1viSampr3vySampqdnZ34wiX1vSSampr1vSOZmZmampr1viT2vSOampr2viT2viSampr2viSampr2vyX4vyWbm5v3vSSdnZ32wSadnZ36wCWcnJyZmZn/wSr/2ySampr2vSP2viSZmZn2vSSZmZn2vST2viSampr2viSbm5ubm5uZmZn1vSSampqbm5v2vSWampqampr3vSf5wiT5vyagoKD/xCmkpKT/yCSZmZn1vSO4V2dEAAAAQHRSTlMA+vsG9fO6uqdgRSIi7+3q39XVqZWVgnJyX09HPDw1NTAwKRkYB+jh3L6+srKijY2Ef2lpYllZUU5CKigWFQ4Oneh1twAAAZlJREFUOMuV0mdzAiEQBmDgWq4YTWIvKRqT2Htv8P//VJCTGfYQZnw/3fJ4tyO76KE0m1b2fZu+U/pu4QGlA7N+Up5PIz9d+cmkbSrSNr9seT3GKeNYIyeO5j16S28exY5suK0U/QKmmeCCX6xs22hJLVkitMImxCvEs8EG3SCRCN/ViFPqnq5epIzZ07QJJvkM9Tkz1xnkmXbfSvR7f4H8AtXBkLGj74mMvjM1+VHZpAZ4LM4K/LBWEI9jwP71v1ZEQ6dyvQMf8A/1pmdZnKce/VH1iIsdte4U8VEtY23xOujxtFpWDgKbfjD2YeEhY0OzfjGeLyO/XfnNpAcmcjDwKOXRfU1IyiTRyEkaiz67pb9oJHJb9vVqKfgjLBPyF5Sq9T0KmSUhQmtiQrJGPHVi0DoSabj31G2gW3buHd0pY85lNdcCk8xlNDPXMuSyNiwl+theIb9C7RLIpKvviYy+M6H8qGwSAp6Is19+GP6KxwnggJ/kq6Jht5rnRQA4z9zyRRaXssvyqp5I6Vutv0vkpJaJtnjpz/8B19ytIayazLoAAAAASUVORK5CYII=");
  font-size: 0.1em;
  color: transparent;
}

.starability-result:after {
  content: ' ';
  position: absolute;
  left: 0;
  height: 30px;
  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAA8CAMAAABGivqtAAAAxlBMVEUAAACZmZn2viTHuJ72viOampqampr1viSampr3vySampqdnZ34wiX1vSSampr1vSOZmZmampr1viT2vSOampr2viT2viSampr2viSampr2vyX4vyWbm5v3vSSdnZ32wSadnZ36wCWcnJyZmZn/wSr/2ySampr2vSP2viSZmZn2vSSZmZn2vST2viSampr2viSbm5ubm5uZmZn1vSSampqbm5v2vSWampqampr3vSf5wiT5vyagoKD/xCmkpKT/yCSZmZn1vSO4V2dEAAAAQHRSTlMA+vsG9fO6uqdgRSIi7+3q39XVqZWVgnJyX09HPDw1NTAwKRkYB+jh3L6+srKijY2Ef2lpYllZUU5CKigWFQ4Oneh1twAAAZlJREFUOMuV0mdzAiEQBmDgWq4YTWIvKRqT2Htv8P//VJCTGfYQZnw/3fJ4tyO76KE0m1b2fZu+U/pu4QGlA7N+Up5PIz9d+cmkbSrSNr9seT3GKeNYIyeO5j16S28exY5suK0U/QKmmeCCX6xs22hJLVkitMImxCvEs8EG3SCRCN/ViFPqnq5epIzZ07QJJvkM9Tkz1xnkmXbfSvR7f4H8AtXBkLGj74mMvjM1+VHZpAZ4LM4K/LBWEI9jwP71v1ZEQ6dyvQMf8A/1pmdZnKce/VH1iIsdte4U8VEtY23xOujxtFpWDgKbfjD2YeEhY0OzfjGeLyO/XfnNpAcmcjDwKOXRfU1IyiTRyEkaiz67pb9oJHJb9vVqKfgjLBPyF5Sq9T0KmSUhQmtiQrJGPHVi0DoSabj31G2gW3buHd0pY85lNdcCk8xlNDPXMuSyNiwl+theIb9C7RLIpKvviYy+M6H8qGwSAp6Is19+GP6KxwnggJ/kq6Jht5rnRQA4z9zyRRaXssvyqp5I6Vutv0vkpJaJtnjpz/8B19ytIayazLoAAAAASUVORK5CYII=");
  background-position: 0 -30px;
}

.starability-result[data-rating="5"]::after {
  width: 150px;
}

.starability-result[data-rating="4"]::after {
  width: 120px;
}

.starability-result[data-rating="3"]::after {
  width: 90px;
}

.starability-result[data-rating="2"]::after {
  width: 60px;
}

.starability-result[data-rating="1"]::after {
  width: 30px;
}

.starability-basic {
  display: block;
  position: relative;
  width: 150px;
  min-height: 60px;
  padding: 0;
  border: none;
}

.starability-basic > input {
  position: absolute;
  margin-right: -100%;
  opacity: 0;
}

.starability-basic > input:checked ~ label,
.starability-basic > input:focus ~ label {
  background-position: 0 0;
}

.starability-basic > input:checked + label,
.starability-basic > input:focus + label {
  background-position: 0 -30px;
}

.starability-basic > input:hover + label::before {
  opacity: 1;
}

.starability-basic > input:focus + label {
  outline: 1px dotted #999;
}

.starability-basic .starability-focus-ring {
  position: absolute;
  left: 0;
  width: 100%;
  height: 30px;
  outline: 2px dotted #999;
  pointer-events: none;
  opacity: 0;
}

.starability-basic > #no-rate:focus ~ .starability-focus-ring {
  opacity: 1;
}

.starability-basic > label {
  position: relative;
  display: inline-block;
  float: left;
  width: 30px;
  height: 30px;
  font-size: 0.1em;
  color: transparent;
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAA8CAMAAABGivqtAAAAxlBMVEUAAACZmZn2viTHuJ72viOampqampr1viSampr3vySampqdnZ34wiX1vSSampr1vSOZmZmampr1viT2vSOampr2viT2viSampr2viSampr2vyX4vyWbm5v3vSSdnZ32wSadnZ36wCWcnJyZmZn/wSr/2ySampr2vSP2viSZmZn2vSSZmZn2vST2viSampr2viSbm5ubm5uZmZn1vSSampqbm5v2vSWampqampr3vSf5wiT5vyagoKD/xCmkpKT/yCSZmZn1vSO4V2dEAAAAQHRSTlMA+vsG9fO6uqdgRSIi7+3q39XVqZWVgnJyX09HPDw1NTAwKRkYB+jh3L6+srKijY2Ef2lpYllZUU5CKigWFQ4Oneh1twAAAZlJREFUOMuV0mdzAiEQBmDgWq4YTWIvKRqT2Htv8P//VJCTGfYQZnw/3fJ4tyO76KE0m1b2fZu+U/pu4QGlA7N+Up5PIz9d+cmkbSrSNr9seT3GKeNYIyeO5j16S28exY5suK0U/QKmmeCCX6xs22hJLVkitMImxCvEs8EG3SCRCN/ViFPqnq5epIzZ07QJJvkM9Tkz1xnkmXbfSvR7f4H8AtXBkLGj74mMvjM1+VHZpAZ4LM4K/LBWEI9jwP71v1ZEQ6dyvQMf8A/1pmdZnKce/VH1iIsdte4U8VEtY23xOujxtFpWDgKbfjD2YeEhY0OzfjGeLyO/XfnNpAcmcjDwKOXRfU1IyiTRyEkaiz67pb9oJHJb9vVqKfgjLBPyF5Sq9T0KmSUhQmtiQrJGPHVi0DoSabj31G2gW3buHd0pY85lNdcCk8xlNDPXMuSyNiwl+theIb9C7RLIpKvviYy+M6H8qGwSAp6Is19+GP6KxwnggJ/kq6Jht5rnRQA4z9zyRRaXssvyqp5I6Vutv0vkpJaJtnjpz/8B19ytIayazLoAAAAASUVORK5CYII=');
  background-repeat: no-repeat;
  background-position: 0 -30px;
}

.starability-basic > label::before {
  content: '';
  position: absolute;
  display: block;
  height: 30px;
  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAA8CAMAAABGivqtAAAAxlBMVEUAAACZmZn2viTHuJ72viOampqampr1viSampr3vySampqdnZ34wiX1vSSampr1vSOZmZmampr1viT2vSOampr2viT2viSampr2viSampr2vyX4vyWbm5v3vSSdnZ32wSadnZ36wCWcnJyZmZn/wSr/2ySampr2vSP2viSZmZn2vSSZmZn2vST2viSampr2viSbm5ubm5uZmZn1vSSampqbm5v2vSWampqampr3vSf5wiT5vyagoKD/xCmkpKT/yCSZmZn1vSO4V2dEAAAAQHRSTlMA+vsG9fO6uqdgRSIi7+3q39XVqZWVgnJyX09HPDw1NTAwKRkYB+jh3L6+srKijY2Ef2lpYllZUU5CKigWFQ4Oneh1twAAAZlJREFUOMuV0mdzAiEQBmDgWq4YTWIvKRqT2Htv8P//VJCTGfYQZnw/3fJ4tyO76KE0m1b2fZu+U/pu4QGlA7N+Up5PIz9d+cmkbSrSNr9seT3GKeNYIyeO5j16S28exY5suK0U/QKmmeCCX6xs22hJLVkitMImxCvEs8EG3SCRCN/ViFPqnq5epIzZ07QJJvkM9Tkz1xnkmXbfSvR7f4H8AtXBkLGj74mMvjM1+VHZpAZ4LM4K/LBWEI9jwP71v1ZEQ6dyvQMf8A/1pmdZnKce/VH1iIsdte4U8VEtY23xOujxtFpWDgKbfjD2YeEhY0OzfjGeLyO/XfnNpAcmcjDwKOXRfU1IyiTRyEkaiz67pb9oJHJb9vVqKfgjLBPyF5Sq9T0KmSUhQmtiQrJGPHVi0DoSabj31G2gW3buHd0pY85lNdcCk8xlNDPXMuSyNiwl+theIb9C7RLIpKvviYy+M6H8qGwSAp6Is19+GP6KxwnggJ/kq6Jht5rnRQA4z9zyRRaXssvyqp5I6Vutv0vkpJaJtnjpz/8B19ytIayazLoAAAAASUVORK5CYII=");
  background-position: 0 30px;
  pointer-events: none;
  opacity: 0;
}

.starability-basic > label:nth-of-type(5)::before {
  width: 120px;
  left: -120px;
}

.starability-basic > label:nth-of-type(4)::before {
  width: 90px;
  left: -90px;
}

.starability-basic > label:nth-of-type(3)::before {
  width: 60px;
  left: -60px;
}

.starability-basic > label:nth-of-type(2)::before {
  width: 30px;
  left: -30px;
}

.starability-basic > label:nth-of-type(1)::before {
  width: 0px;
  left: 0px;
}

@media screen and (-webkit-min-device-pixel-ratio: 2), screen and (min-resolution: 192dpi) {
  .starability-basic > label {
    background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAB4CAMAAACZ62E6AAABAlBMVEUAAACZmZmampr2vSObm5v/yiufn5+ampr1viP1viSZmZn2viOZmZmampqampr2viSampqampqcnJz5vyScnJz3wSf/wyn/xiujo6Oqqqr/0C/1vSOampr2viP2viOampr2viP2vST2viOampqampqampr1vyP3viSampr2vyT4vyX3viSbm5ubm5v5wCT8xSmgoKCampqampr3vyb2wiWenp72viOampqZmZmampr2viP2viP1viSampqbm5v2vyT3viObm5v4vyadnZ34wSSbm5v2viSZmZn2viP2vST2viP2viT1viOZmZn2viT2viX3viT3vyb2vyOZmZn1vSOZmZlNN+fKAAAAVHRSTlMA9uz4PQwS8O7r5+fTw4yMelw2MB0dFRELBgbS+/Hfu7uxqKWdg4N7ZmZMPi8pKRgPs0w7Nhb14drKw6Gck21tXkNDIyMZ1rDLycTBtaqVknlfV0sGP8ZwAAADW0lEQVRYw9zWvYqDQBSG4TPDoCAqKhYKQgoVLFaIgZCkiCBBUqVazv3fyu4aEXWdM85Uy779A+LP58AfTQgw73AwtxFiZIwbxMbUfuB3H4b49YNfZrbGodoI52+cm9hH9sbZwwAXOFbo2zjDsSzWxnecuuvaM8MpdtbEPs7y9azF5phZWrjERaWOPdpLbB81cICrgv3W4mvMLbU6RmFQeA5u5HhFEEbHLdWLsMxvHJXxW16Goh+ZqPyny1Az5j79SsCJoWHsBNAxQ9sNF26bWFuMC8v1LY+mmeTadjaqtaNnnXoxWBcde1nNWnzdb68xrOqvu22/MTzuPutujpJ122NvluSb8tTWk85CclDZQwLS0oa2TQpEKacsJy0kSJaQOKJxROKKxhWJ7zS+k9ijsUdim8Y2ZWNUFBP4pMKfOv8onX9WrsI5gd3VVLXtatxcuU0znGUHCUAS2DgrS6mT6hTzrXEjfIZj5Dk2xKkihqm4wKlQfQRqalhUP9UHo3FIPAG/Et44JVLsDDf0JHmB3OEByOwZES8hSAsviGjBdh3ylh6plmMnW4IyAUVJWcE/76vTell1EIaiMBwIAcWBA9GC0lIdKFXQQUsHVVCklN7ojf3+z3JOxYqK2TH555+K6CJJQtRbr9XtDmCnjH0AX9Va8J+liIMvDtRsCk2pEs6hKVexR2g7KuDihwt5a9MfprY0fkLXU9ZmFLpoJolN6GXKWWfZx0tHCocwKJSxC22ItYUEjmBUJHFjfYz1xQxlfaLiZsBExq2IPtbkNbLtOwwuGgjTLkH43mYtSzam7+1Bsr3nm5uExBQUozEh9V7N7uvmwZcqdpm0C6vJW63bZEuXtbrV2zpDzhrpYLBWMnY1mjV7JWFtMio7zbWniWFxvHnWm1yGxXmOPXP+L3YV2ysjnNhaZNeMcHPvuL27BMnVMaujljBAYyje4niH4g2ONyh+4PiB4gOODyjWcKxh1gZBNoJjEY4R/BLhF4IDEQ4QPBoEoyxH4+bxrUsHyxwxQlg0WHXqYifVLmo67cKY/UtaXFxBV26TLjuHrkp8BPJTMij1xQejdkgO24nf7dBOCRcbzQuNOR9Qs64GzzrfQa8It2oFAA6Zrga9xEeq1KHmLUHIiCAWInsg1x/MLqkMsItF8QAAAABJRU5ErkJggg==");
    background-size: 30px auto;
  }
}

</style>

@Atinux I know that you're probably really busy with other things. But we would love your input on this issue that was closed but seems to be persisting for some people. Thanks!

Using v-show instead of v-if and v-else solved the issue for me. That being said I do not know why v-if is causing this issue.

@NetBzz
I am not using Nuxt, but I do have a SSR app. I came across a similar issue.

The reason v-show works and v-if does not is that v-if actually removes the element. There is some sort of inconsistency in your data (for me it was a randomization of items shown) when it is rendered vs. when it is hydrated. So some items caused my v-if not to render an element based on item.property.

So randomization doesn't matter as long as the items being randomized have identical properties, and generate identical DOM structure.

As you can see here

In development mode, Vue will assert the client-side generated virtual DOM tree matches the DOM structure rendered from the server. If there is a mismatch, it will bail hydration, discard existing DOM and render from scratch.

Client side hydration only cares about structure, not content. Therefore a link with v-show="false" will still output <a></a> and structure will validate even if your content is randomized. If your item generates different structure for client-side than initial render it will throw this error.

For me, my structure looked like this:

items: [
    {
        title: 'foo',
        ...
        more: 'google.com',
    },
    {
        title: 'bar',
        ...
        more: null,
    },
    {
        title: 'baz',
        ...
        more: 'google.com',
    },
    {
        title: 'f00',
        ...
        more: null
    },
]

I was picking two of those at random, and outputting as such.

...
<h1>{{ item.title }}</h1>
<a 
    v-if="item.more"
    :href="item.more"
>
    Read More
</a>
...

So if inital render picked items[0] and items[1] and client side picked items[0] and items[2] client side hydration would fail. What made it tricky to catch was that if inital render picked items[0] and items[1] and client side picked items[2] and items[3] client hydration was successful.

Simple fix was using v-show to ensure structure mached for client side hydration.
Since some screen readers still pick up hidden links, make sure you add appropriate aria tags and something like this

<a
    v-show="item.more"
    v-html="item.more ? 'More' : '' "
    :aria-hidden="item.more ? false : true "
    :href="item.more"
></a>

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

surmon-china picture surmon-china  路  3Comments

shyamchandranmec picture shyamchandranmec  路  3Comments

mattdharmon picture mattdharmon  路  3Comments

VincentLoy picture VincentLoy  路  3Comments

mikekidder picture mikekidder  路  3Comments