⚪ SVG-Powered component to easily create skeleton loadings.

Overview

react-content-loader

Example's react-content-loader

SVG-Powered component to easily create placeholder loadings (like Facebook's cards loading).

Features

  • ⚙️  Customizable: Feel free to change the colors, speed, sizes and even RTL;
  • 👌  Plug and play: with many presets to use, see the examples;
  • ✏️  DIY: use the create-content-loader to create your own custom loaders easily;
  • 📱 React Native support: same API, as same powerful features;
  • ⚛️ Really lightweight: less than 2kB and 0 dependencies for web version;

Index

Getting Started

npm i react-content-loader --save
yarn add react-content-loader

For React Native

npm i react-content-loader react-native-svg --save
yarn add react-content-loader react-native-svg

CDN from JSDELIVR

Usage

There are two ways to use it:

1. Presets, see the examples:

import ContentLoader, { Facebook } from 'react-content-loader'

const MyLoader = () => <ContentLoader />
const MyFacebookLoader = () => <Facebook />

2. Custom mode, see the online tool

const MyLoader = () => (
  <ContentLoader viewBox="0 0 380 70">
    {/* Only SVG shapes */}    
    <rect x="0" y="0" rx="5" ry="5" width="70" height="70" />
    <rect x="80" y="17" rx="4" ry="4" width="300" height="13" />
    <rect x="80" y="40" rx="3" ry="3" width="250" height="10" />
  </ContentLoader>
)

Still not clear? Take a look at this working example at codesandbox.io
Or try the components editable demo hands-on and install it from bit.dev

Native

react-content-loader can be used with React Native in the same way as web version with the same import:

1. Presets, see the examples:

import ContentLoader, { Facebook } from 'react-content-loader/native'

const MyLoader = () => <ContentLoader />
const MyFacebookLoader = () => <Facebook />

2. Custom mode

To create custom loaders there is an important difference: as React Native doesn't have any native module for SVG components, it's necessary to import the shapes from react-native-svg or use the named export Rect and Circle from react-content-loader import:

import ContentLoader, { Rect, Circle } from 'react-content-loader/native'

const MyLoader = () => (
  <ContentLoader viewBox="0 0 380 70">
    <Circle cx="30" cy="30" r="30" />
    <Rect x="80" y="17" rx="4" ry="4" width="300" height="13" />
    <Rect x="80" y="40" rx="3" ry="3" width="250" height="10" />
  </ContentLoader>
)

Options

Prop name and type
Environment Description
animate?: boolean
Defaults to true
React DOM
React Native
Opt-out of animations with false
title?: string
Defaults to Loading interface...
React DOM only It's used to describe what element it is. 
Use '' (empty string) to remove.
baseUrl?: string
Defaults to an empty string
React DOM only Required if you're using <base url="/" /> document <head/>
This prop is common used as: 
<ContentLoader baseUrl={window.location.pathname} /> which will fill the SVG attribute with the relative path. Related #93.
speed?: number
Defaults to 1.2
React DOM
React Native
Animation speed in seconds.
interval?: number
Defaults to 0.25
React DOM
React Native
Interval of time between runs of the animation, 
as a fraction of the animation speed.
viewBox?: string
Defaults to undefined
React DOM
React Native
Use viewBox props to set a custom viewBox value,
for more information about how to use it,
read the article How to Scale SVG.
gradientRatio?: number
Defaults to 1.2
React DOM only Width of the animated gradient as a fraction of the view box width.
rtl?: boolean
Defaults to false
React DOM
React Native
Content right-to-left.
backgroundColor?: string
Defaults to #f5f6f7
React DOM
React Native
Used as background of animation.
foregroundColor?: string
Defaults to #eee
React DOM
React Native
Used as the foreground of animation.
backgroundOpacity?: number
Defaults to 1
React DOM only Background opacity (0 = transparent, 1 = opaque)
used to solve an issue in Safari
foregroundOpacity?: number
Defaults to 1
React DOM only Animation opacity (0 = transparent, 1 = opaque)
used to solve an issue in Safari
style?: React.CSSProperties
Defaults to {}
React DOM only
uniqueKey?: string
Defaults to random unique id
React DOM only Use the same value of prop key, 
that will solve inconsistency on the SSR, see more here.

See all options live

Examples

Facebook Style
import { Facebook } from 'react-content-loader'

const MyFacebookLoader = () => <Facebook />

Facebook Style

Instagram Style
import { Instagram } from 'react-content-loader'

const MyInstagramLoader = () => <Instagram />

Instagram Style

Code Style
import { Code } from 'react-content-loader'

const MyCodeLoader = () => <Code />

Code Style

List Style
import { List } from 'react-content-loader'

const MyListLoader = () => <List />

List Style

Bullet list Style
import { BulletList } from 'react-content-loader'

const MyBulletListLoader = () => <BulletList />

Bullet list Style

Custom Style

For the custom mode, use the online tool.

const MyLoader = () => (
  <ContentLoader
    height={140}
    speed={1}
    backgroundColor={'#333'}
    foregroundColor={'#999'}
    viewBox="0 0 380 70"
  >
    {/* Only SVG shapes */}
    <rect x="0" y="0" rx="5" ry="5" width="70" height="70" />
    <rect x="80" y="17" rx="4" ry="4" width="300" height="13" />
    <rect x="80" y="40" rx="3" ry="3" width="250" height="10" />
  </ContentLoader>
)

Custom

Troubleshooting

Responsive - Mobile version

In order to avoid unexpected behavior, the package doesn't have opinioned settings. So if it needs to be responsive, have in mind that the output of package is a regular SVG, so it just needs the same attributes to become a regular SVG responsive, which means:

import { Code } from 'react-content-loader'

const MyCodeLoader = () => (
  <Code
    width={100}
    height={100}
    viewBox="0 0 100 100"
    style={{ width: '100%' }}
  />
)

Server-side rendering (SSR) - Match snapshot

As the main component generates random values to match the id of the SVG element with background style, it can encounter unexpected errors and unmatching warning on render, once the random value of id will be generated twice, in case of SSR: server and client; or in case of snapshot test: on the first match and re-running the test.

To fix it, set the prop uniqueKey, then the id will not be random anymore:

import { Facebook } from 'react-content-loader'

const MyFacebookLoader = () => <Facebook uniqueKey="my-random-valye" />

Alpha is not working: Safari / iOS

When using rgba as a backgroundColor or foregroundColor value, Safari does not respect the alpha channel, meaning that the color will be opaque. To prevent this, instead of using a rgba value for backgroundColor/foregroundColor, use the rgb equivalent and move the alpha channel value to the backgroundOpacity/foregroundOpacity props.

{/* Opaque color in Safari and iOS */}
<ContentLoader
  backgroundColor="rgba(0,0,0,0.06)"
  foregroundColor="rgba(0,0,0,0.12)">


{/_ Semi-transparent color in Safari and iOS _/}
<ContentLoader
    backgroundColor="rgb(0,0,0)"
    foregroundColor="rgb(0,0,0)"
    backgroundOpacity={0.06}
    foregroundOpacity={0.12}>

Black box in Safari / iOS (again)

Using the base tag on a page that contains SVG elements fails to render and it looks like a black box. Just remove the base-href tag from the <head /> and issue solved.

black box

See: #93 / 109

Browser supports SVG-Animate

Old browser doesn't support animation in SVG (compatibility list), and if your project must support IE for examples, here's a couple of ways to make sure that browser supports SVG Animate:

  • window.SVGAnimateElement
  • document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#SVG-Animation", "1.1")
  • Or even use https://modernizr.com/

Similar packages


Development

Fork the repo then clone it

$ git clone [email protected]:YourUsername/react-content-loader.git && cd react-content-loader

$ npm i: Install the dependencies;

$ npm run build: Build to production;

$ npm run dev: Run the docz to see your changes;

$ npm run test: Run all tests: type checking, unit tests on web and native;

$ yarn test:watch: Watch unit tests;

$ yarn tsc: Typescript checking;

$ yarn tsc:watch: Typescript checking with watching;

Commit messages

Commit messages should follow the commit message convention so, changelogs could be generated automatically by that. Commit messages are validated automatically upon commit. If you aren't familiar with the commit message convention, you can use yarn commit (or npm run commit) instead of git commit, which provides an interactive CLI for generating proper commit messages.

License

MIT

Issues
  • Not working in Safari.

    Not working in Safari.

    What did you do?

    My Loader Component

    const Loader = props => (
      <ContentLoader
        preserveAspectRatio="none"
        style={{width: '100%' }}
      >
        <rect x="0" y="0" rx="5" ry="5" width="100%" height={300} /> 
      </ContentLoader>
    )
    

    What did you expect to happen?

    Expect to work for all browsers

    What happened actually?

    Working fine on Chrome and FireFox but giving black layout for safari. image

    Which versions of react-content-loader, and which browser are affected by this issue?

    "react-content-loader": "^3.1.1" "react": "^15.4.2" Browsers: Safari

    bug Solved Needs doc released 
    opened by Ekluv 27
  • When unmounting component with ContentLoader a LOOP Warning is thown

    When unmounting component with ContentLoader a LOOP Warning is thown

    Im using ContentLoader inside a LoadingListItem Component. When a flag is changed I unmount this component to ListItem BUT when this happens a WARNING is thrown , this warning is consuming the memory.

    Warning: Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op.

    Please check the code for the ContentLoader component.

    help wanted feature released 
    opened by beickon 19
  • Text error

    Text error

    What did you do?

    Please include the actual source code causing the issue. import { Facebook } from 'react-content-loader'; // then in render method return <Facebook />;

    What did you expect to happen?

    Please mention the expected behaviour. See the facebook loader

    What happened actually?

    Invariant Violation: Text string must be rendered within a component, error located at title in Svg

    Which versions of react-content-loader, and which browser are affected by this issue?

    Please also mention the version of react. Everything is the latest

    bug waiting answer released 
    opened by virtualLast 17
  • Option to remove view box

    Option to remove view box

    This is not a bug, but a question/discussion

    I'm not sure if I'm using svg's properly but for having responsive Skeletons, I thought of disabling viewBox. And I did so by passing unexpected values to width/height. Then by skeleton loader was responsive in the way I want (more with in desktop, same height for rectangles)

    1- Do you think that's correct approach for this kind of svgs? 2- If you answered yes/maybe, can we add an option to remove view box?

    feature 
    opened by dogancana 14
  • SSR matching of fill url

    SSR matching of fill url

    Using react-content-loader with SSR (in this case with Next.js) I'm getting the warning:

    Warning: Prop `style` did not match. Server: "fill:url(#yu80c54k1c8)" Client: "fill:url(#zhqtwhb70bm)"
    

    Any workaround?

    Thanks!

    opened by pdrbrnd 10
  • Doesn't work with Expo (React Native)

    Doesn't work with Expo (React Native)

    Not sure exactly why but the error is this one.

    Tried to register two views with the same name RNSVGRect

    opened by jordymeow 10
  • Run local build w/ RN

    Run local build w/ RN

    I'm trying to work on a fork of this library but unfortunately I can't seem to get it to build in way that my RN project likes it. My steps:

    cd react-content-loader
    npm i
    npm run build
    cd ../rn-app
    npm link ../react-content-loader
    

    It seems like the version that gets pulled from npm is structured in a totally different way than what gets built. I'm seeing folders named "stylized" that I don't get when doing npm run build

    opened by ds8k 9
  • View config not found for name rect

    View config not found for name rect

    What did I do?

    I write this code and I expected to run properly this is my code :

    
    const MyLoader = props => (
      <ContentLoader
        height={130}
        width={400}
        speed={2}
        primaryColor="#f3f3f3"
        secondaryColor="#ecebeb"
        {...props}
      >
        <rect x="19" y="45" rx="3" ry="3" width="245" height="5" /> 
        <circle cx="333.5" cy="78.76" r="49.5" /> 
        <rect x="19" y="75" rx="3" ry="3" width="245" height="5" /> 
        <rect x="19" y="105" rx="3" ry="3" width="245" height="5" />
      </ContentLoader>
    )
    
    render() {
      return(
          <MyLoader/>
      )
    }
    

    And i got this error

    Invariant Violation: Invariant Violation: Invariant Violation: Invariant Violation: View config not found fot name rect

    I used the last version of this library

    Solved released 
    opened by mahdidavoodi7 9
  • RTL switch not working

    RTL switch not working

    I flipped the rtl flag on the component - seems that the navigation has changed, but the content stayed the same. Do I need to make my own RTL component? I thought it would switch around automatically. I went to http://danilowoz.com/create-content-loader/ and switching RTL flag also does nothing. Thanks

    feature released 
    opened by adamgajzlerowicz 8
  • Refactored build infrastructure

    Refactored build infrastructure

    Profits? Smaller build (and less bytes added to the host app, by removing uuid dependency), better tree-shakeability for upcoming [email protected]

    opened by Andarist 8
  • Add support for top-down gradient animation

    Add support for top-down gradient animation

    Adding gradientDirection prop which translates into a rotate transformation applied to the linearGradient SVG element. Providing the option to animate either from left to right or top to bottom.

    fix #255

    Summary

    This is related to #255. I was browsing for Hactoberfest tagged issues and this one seemed quite interesting. Plus, I love what you've created here, so I'm glad to contribute.

    Related Issue #255

    Any Breaking Changes

    No breaking changes :)

    Checklist

    • [X] Are all the test cases passing?
    • [X] If any new feature has been added, then are the test cases updated/added?
    • [X] Has the documentation been updated for the proposed change, if required?

    Demo

    Kapture 2021-10-14 at 23 15 26

    opened by moQuez 1
  • Animation isn't happening till entire page loads

    Animation isn't happening till entire page loads

    The animation should happen as soon as possible. Instead, it is happening after the entire page is loaded. Till the entire page loads, It's static.

    opened by mouryareddy 4
  • Top-down animation

    Top-down animation

    Hello all, there is default animation from left to right, but is there some way how to make top-down animation?

    help wanted Hacktoberfest good first issue 
    opened by vlkpa 1
  • confused viewBox in react-native

    confused viewBox in react-native

    What did you do?

    Please include the actual source code causing the issue.

    import React from 'react'
    import ContentLoader, { Rect } from 'react-content-loader/native'
    
    const MyLoader = (props) => (
      <ContentLoader
        speed={2}
        width="100%"
        height="100%"
        viewBox="0 0 100 60"
        backgroundColor="#f3f3f3"
        style={{ backgroundColor: 'red' }}
        foregroundColor="#ecebeb"
        // {...props}
      >
        <Rect x="0" y="0" rx="2" ry="2" width="40" height="60" />
        <Rect x="45" y="0" rx="2" ry="2" width="40" height="60" />
      </ContentLoader>
    )
    
    export default MyLoader
    
    // use
    <View style={{ height: 75, width: '100%' }}>
      <MyCodeLoader />
    </View>
    

    What did you expect to happen?

    Please mention the expected behaviour. image

    What happened actually?

    image

    Which versions of react-content-loader, and which browser are affected by this issue?

    Please also mention the version of react.

    opened by GreatAuk 2
  • chrome extension to create skeleton directly from the DOM

    chrome extension to create skeleton directly from the DOM

    What did you do?

    This package is great, I'd like to make it even easier to build custom skeleton. I'd like a chrome extension where you select a DOM node, and it generates the skeleton based on the elements of it

    What did you expect to happen?

    This could be inside this repo or another repo by the community

    opened by sibelius 1
  • High CPU usage

    High CPU usage

    image As shown in the above image the home page's cpu usage is always more than 40% and also more 20% in my app. I think this is abnormal, please confirm whether it is a bug or the normal phenomenon?

    enhancement help wanted 
    opened by vylan 15
Releases(v6.0.3)
Owner
Danilo Woznica
Brazilian frontend developer based in Porto, Portugal. Design-driven developer focused on crafting products in ReactJS.
Danilo Woznica
A collection of loading indicators animated with CSS for React

react-spinkit A collection of loading indicators animated with CSS for React Currently I've ported all the spinner animations from Spinkit. If you hav

Kyle Mathews 1.4k Oct 2, 2021
react-loader - React component that displays a spinner via spin.js until your component is loaded.

react-loader react-loader provides your React.js component a simple mechanism for rendering a loading spinner (via spin.js) while data is loading, suc

Cognizant Studio 529 Sep 16, 2021
:cyclone: Simple react.js component for an inline progress indicator

react-progress-button Simple React component for a circular Progress Button. Demo Install npm install react-progress-button --save Example Controlled

Mathieu Dutour 517 Sep 11, 2021
Loading Bar (aka Progress Bar) for Redux and React

React Redux Loading Bar A React component that provides Loading Bar (aka Progress Bar) for long running tasks. Consists of: React component — displays

Anton Mironov 914 Sep 20, 2021
Amazing collection of React spinners components with pure css

React Spinners CSS Loaders (Vue, Angular) Amazing collection of React spinners components with pure css. The React spinners are based on loading.io an

Josh Kuttler 274 Sep 24, 2021
3D animated react button component with progress bar.

3D animated react button component with progress bar.

MD. Ariful Alam 68 Oct 5, 2021
Creates a download handler function and gives progress information

Creates a download handler function and gives progress information

Olavo Parno 57 Sep 15, 2021
A collection of loading spinner components for react

React Spinners A collection of loading spinners with React.js based on Halogen. This package is bootstraped using react-npm-boilerplate Demo Demo Page

David Hu 2k Oct 12, 2021
❄️ The ultimate Line Progress Bar UI for React - Supports 🌸 Natural color gradients & ☃️ Coherent border rounding

Frogress ❄️ The ultimate Line Progress Bar UI for React @frogress/line ?? Installation # Install peer depedencies yarn add react react-dom styled-comp

Junho Yeo 12 Sep 6, 2021
Progress component for React and React Native

react-progress-label Progress component for React and React Native Installation yarn add react-progress-label npm install react-progress-label --save

SWIFT CARROT Technologies 95 May 16, 2021
Easy way to block the user from interacting with your UI.

react-block-ui Easy way to block the user from interacting with your UI. About This library contains easy to use components to prevent the user from i

Availity 271 Sep 13, 2021