Code Monkey home page Code Monkey logo

vue-client-only's Introduction

vue-client-only

NPM version NPM downloads CircleCI donate

Install

yarn add vue-client-only

This project is previously known as vue-no-ssr, switch to 1.x branch for the old docs.

Usage

<template>
  <div id="app">
    <h1>My Website</h1>
    <client-only>
      <!-- this component will only be rendered on client-side -->
      <comments />
    </client-only>
  </div>
</template>

<script>
  import ClientOnly from 'vue-client-only'

  export default {
    components: {
      ClientOnly
    }
  }
</script>

Placeholder

Use a slot or text as placeholder until <client-only /> is mounted on client-side.

eg, show a loading indicator.

<template>
  <div id="app">
    <h1>My Website</h1>
    <!-- use slot -->
    <client-only>
      <comments />
      <comments-placeholder slot="placeholder" />
    </client-only>
    <!-- or use text -->
    <client-only placeholder="Loading...">
      <comments />
    </client-only>
  </div>
</template>

<script>
  import ClientOnly from 'vue-client-only'

  export default {
    components: {
      ClientOnly
    }
  }
</script>

By default the placeholder will be wrapped in a div tag, however you can use placeholderTag prop to customize it:

<client-only placeholder="loading" placeholder-tag="span">
  <comments />
</client-only>

And you get:

<span class="client-only-placeholder">
  loading
</span>

If prop placeholder is an empty string (or null) and no placeholder slot is found, then <client-only> will render the Vue placeholder element <!----> instead of rendering the placholder-tag during SSR render.

Development

yarn install

# Run example
yarn example

Contributing

  1. Fork it!
  2. Create your feature branch: git checkout -b my-new-feature
  3. Commit your changes: git commit -am 'Add some feature'
  4. Push to the branch: git push origin my-new-feature
  5. Submit a pull request :D

Author

vue-client-only © egoist, Released under the MIT License.
Authored and maintained by egoist with help from contributors (list).

egoist.moe · GitHub @egoist · Twitter @_egoistlily

vue-client-only's People

Contributors

anteriovieira avatar atinux avatar clarkdo avatar dependabot-preview[bot] avatar egoist avatar iamandrewluca avatar jonaskuske avatar kirankumarambati avatar tmorehouse avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

vue-client-only's Issues

Feature-request: Work with transition

Currently it sort of just appears when the client side loads. Is there any way to use a transition?

<transition name="slide">
    <no-ssr>
        <div>stuff</div>
    </no-ssr>
</transition>

Doesn't seem to work. We probably need to load the inside as hidden then show it to make the transition work.

[Question] How does it work with a real component that has to be imported?

Hi.

I have tried to find a real exmample and the only one is with a comments component not imported anywhere.

Whow does this work with a real component that has to be imported?

Some like:

<tamplate> ...
  <client-only>
    <realcomponent />
  </client-only>
...


<script>
import ClientOnly from 'vue-client-only'
import realcomponent from 'realcmponent'
...

components: {
  ClientOnly,
  realcomponent,
}

Thanks.

ReferenceError: window is not defined

despite using client only code the above error is generated.
For example using this @johmun/vue-tags-input repository.

the reason is that when we import this in the component, this creates an error.

import ClientOnly from "vue-client-only";
import VueTagsInput from "@johmun/vue-tags-input";
export default {
...
...

Template:


<vue-client-only>
    <vue-tags-input v-model="tag" :tags="tags" @tags-changed="newTags => tags = newTags" />
  </vue-client-only>

....
...
so how can we import the js with window and docuemnt variables without generating an error?

[vue-router] Failed to resolve async component default: ReferenceError: window is not defined
[vue-router] uncaught error during route navigation:
ReferenceError: window is not defined
at Object. (/projects/test/hacker/node_modules/@johmun/vue-tags-input/dist/vue-tags-input.js:1:268)
at Module._compile (module.js:643:30)
at Object.Module._extensions..js (module.js:654:10)
at Module.load (module.js:556:32)
at tryModuleLoad (module.js:499:12)
at Function.Module._load (module.js:491:3)
at Module.require (module.js:587:17)
at require (internal/module.js:11:18)
at r (/projects/test/hacker/node_modules/vue-server-renderer/build.dev.js:9295:16)
at Object. (server-bundle.js:3772:18)
at webpack_require (server-bundle.js:27:30)
at Object.117 (4.server-bundle.js:24:81)
at webpack_require (server-bundle.js:27:30)
at Object.116 (4.server-bundle.js:8:191)
at webpack_require (server-bundle.js:27:30)
at Object.81 (4.server-bundle.js:836:96)

v-if conditions exec server side while inside no-ssr

https://codesandbox.io/s/jnxqqyw0v9 (click on No-SSR Problem)

When a v-if is placed in elements below no-ssr, they still get evaluated server side. We see this not only in markup, but even if we v-if'ed a component. I thought no-ssr prevented things from executing server side?

<template>
  <div>
    <no-ssr>
      <div v-if="blah.blarg">This blows up server side??!</div>
    </no-ssr>
  </div>
</template>
<script>
export default {
  data() {
    return {
      blah: null
    };
  }
};
</script>

Placeholder generates invalid HTML markup

Because the markup of the vue-no-ssr placeholder is a div, it can generate invalid HTML markup if it is nested inside an inline element (or a block element that only accepts inline element).

This code is valid:

<div><no-ssr>Lorem</no-ssr></div>
<div><div class="no-ssr-placeholder"></div></div>

This code is invalid:

<p><no-ssr>Lorem</no-ssr></div>
<p><div class="no-ssr-placeholder"></div></p>

And Nuxt will output the following error:

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.

Suggested solution
Insert the No-SRR placeholder with a <span> instead of a <div>.

Placeholder Slot does not work

Hey thanks for that lib at first!

I'm using it with Nuxt.js and tried to display a loader in the mentioned placeholder.
Always getting [vue-no-ssr] You cannot use multiple child components

<no-ssr>
  <b-table :items="items" />
  <div slot="placeholder">
    <h5>Loading...</h5>
  </div>
</no-ssr>

Use case?

Any use case or reasons to render some part on client and some on server?

[Vue warn]: Multiple root nodes returned from render function. Render function should return a single root node.

When having a construct like this for a component, I get the following error due to the reason that the funcational component returns actually two elements.

<template>
    <no-ssr>
       lalala
    </no-ssr>
</template>

Error I get: [Vue warn]: Multiple root nodes returned from render function. Render function should return a single root node.

I guess it has somethign todo with the return value of the render function:

return h(
      props.placeholderTag,
      {
        class: ['no-ssr-placeholder']
      },
      props.placeholder || placeholderSlot
)

How can I ensure that in this case there is actually only one element returned (I don't need a placeholder)

Thanks
Simon

Client-only content doesn't render in component's slot

Original issue reported at nuxt/nuxt.js#8579.

The content inside <client-only> tag doesn't render when the tag is placed in a component's slot of another component's slot, as shown in the following reproduction:
codesandbox

@egoist any chance you could look into this issue please? I can see the repo hasn't been updated in a while but this missing functionality is crucial for some use-cases, when client-only tag is the only way to go in the nested slots structure :/

Proposal: Renaming to Client-Only

Issuehunt badges

Hey there,

As you know, we are using <no-ssr> in Nuxt.js and after looking at this PR (nuxt/nuxt#5941), I do believe the right naming should be <client-only>.

I know that VuePress actually uses this naming as well: https://vuepress.vuejs.org/guide/using-vue.html#browser-api-access-restrictions

What do you think?


IssueHunt Summary

[
<
i
m
g

s
r
c

'
h
t
t
p
s
:
/
/
a
v
a
t
a
r
s
2
.
g
i
t
h
u
b
u
s
e
r
c
o
n
t
e
n
t
.
c
o
m
/
u
/
9
0
4
7
2
4
?
v

4
'

a
l
t

'
a
t
i
n
u
x
'

w
i
d
t
h

2
4

h
e
i
g
h
t

2
4

a
t
i
n
u
x
]
(
h
t
t
p
s
:
/
/
i
s
s
u
e
h
u
n
t
.
i
o
/
u
/
a
t
i
n
u
x
)

h
a
s

b
e
e
n

r
e
w
a
r
d
e
d
.

Backers (Total: $100.00)

Submitted pull Requests


Tips


IssueHunt has been backed by the following sponsors. Become a sponsor

Environment

@egoist

Instead of using

process.env.NODE_ENV === 'development'

Can we change to the code below?

process.browser !process.browser

Vue.runtime.esm.js setAttribute is not a function

So upon upgrading to vue-no-ssr 1.1.0 I see this error, it does not appear on 1.0.0. I wasn't 100% sure if it was something in my code or this library but I believe it is triggered my something in the latest changes. For some reason I only see this error in production.
The error points to vue.runtime.esm.js

el.setAttribute('class', cls)
el.setAttribute is not a function

Here's my code:

no-ssr(placeholder="loading")
    //- Input
    .layout.row.mt-4(v-if="user")
        social-avatar.mr-3(:user="user")
        v-text-field(
            v-model="commentModel"
            name="social-comments"
            append-icon="send"
            :placeholder="$t('social:comments.add_a_comment')"
            ref="input"
            :loading="loading"
            color="accent"
            @click:append="submit"
            @keyup.enter="submit"
            outline
        )

2018-11-27 11 20 48

Usage with v-if

Is there a way to use no-ssr conditionally? Currently I'm trying this:

<no-ssr>
    <some-component v-if="condition"></some-component>
</no-ssr>

but I'm getting the following erro:

client.js:50 TypeError: Cannot read property 'length' of undefined
    at Proxy.render (no-ssr.js:18)
    at VueComponent.Vue._render (vue.runtime.esm.js:4191)
    at VueComponent.updateComponent (vue.runtime.esm.js:2570)
    at Watcher.get (vue.runtime.esm.js:2913)
    at Watcher.run (vue.runtime.esm.js:2990)
    at flushSchedulerQueue (vue.runtime.esm.js:2756)
    at Array.<anonymous> (vue.runtime.esm.js:694)
    at nextTickHandler (vue.runtime.esm.js:641)
    at <anonymous>

Any idea if this is possible?

I tried using v-if on <no-ssr>, but this gives me errors since I'm using Nuxt.js.

react-snap compatibility

Hey, I would like to use this component in one of my projects, however, I am using react-snap to prerender it, which this component does not appear to work with. If you were willing to merge it I can make a PR to include the functionality to not render the child component(s) when using react-snap as well as traditional SSR.

[BUG] using script inside client-only not working in the build

hello,
using client-only with script does not work, in development mode the script is loaded but after the build does not work.
I changed it to use with vue-meta, but I couldn't understand why these two different behaviors.
Example

<client-only>
  <script src="https://www.google.com"></script>
</client-only>

I know it's not the right way to use it, but with <no-ssr> it worked

Can't access element client side via this.$refs

<client-only>
    <vue-bootstrap-typeahead 
      class="ctl" 
      :type="type" 
      :data="typeahead" 
      :id="name" 
      :name="name" 
      ref="inputRef" 
      :minMatchingChars="1" 
      :value="value" size="lg" 
      @hit="updateValue" 
      @input="updateValue">
    </vue-bootstrap-typeahead>
    <input 
      class="form-control form-control-lg ctl form-control" 
      :type="type" 
      slot="placeholder" 
      :name="name" 
      ref="inputPlaceholderRef" 
      :value="value" />
</client-only>

I'm using the client-only that Nuxt imports. I have a component that only works client side vue-bootstrap-typeahead so I've wrapped it in client-only and filled the placeholder slot with a normal input. Problem is I was setting this.$refs.inputRef.value = value on the client side but the this.$refs doesn't include inputRef. inputPlaceholderRef does show up, however.

Is there a way in which this could work? In the meantime, maybe there is a work around?

Dependabot couldn't reach registry.npm.taobao.org as it timed out

Dependabot couldn't reach registry.npm.taobao.org as it timed out.

Is registry.npm.taobao.org accessible over the internet? If it is then this may be a transitory issue and can be ignored - Dependabot will close it on its next successful update run.

You can mention @dependabot in the comments below to contact the Dependabot team.

Is there a need to update component for usage with Vue 3?

As in Vue 3 arguments are no longer passed to render(), component obviously will not work. We also know, vue-client-only is heavily used in Nuxt, thus I presume is heavily maintained. Are there any plans on updating this particular package to support Vue 3?

SSR loading template

This lib is awesome, thanks for your work!

Is it easy to extend placeholder, so instead of just text I could use a vue template?

My desired workflow would be to render "placeholder" using actual data I already have on the server and to replace it on frontend so client does not see any jumping page after fully loaded component.

For instance I would like to use:
https://github.com/egoist/vue-content-loader
on initial frame from the server.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.