---
title: Percentage Progress Bar
product: Form Library
description: Learn how to add a progress bar with percentage to your web form to keep track of unanswered questions. View a free demo for JavaScript to see this useful feature in action. Enhance the user experience and increase form completion rates.
framework: React
source: https://surveyjs.io/form-library/examples/progress-bar-with-percentage/reactjs
index: https://surveyjs.io/form-library/examples/overview.md
---

# Percentage Progress Bar (React)

To help respondents keep track of answered and unanswered questions, your survey can display a progress bar that indicates a percentage of survey completion. Follow the instructions below to implement the percentage progress bar in your application:

1. Create a custom component that renders the progress bar.         
You can implement the progress bar based on a simple `<div>` element. Fill this `<div>` with color depending on `SurveyModel`'s [`progressValue`](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#progressValue) property value.

1. Display a percentage value and a title.       
A percentage value is already stored in the `progressValue` property. To store the title, you need to create a custom property&mdash;`progressTitle`. Call `Serializer`'s `addProperty` method to add the property to the survey. Then, specify the property value in the survey JSON schema.

1. Register the custom component so that it can be accessed by name.            
    In HTML/CSS/JavaScript projects, register the component in `ReactElementFactory` as shown in the `index.js` file.           
    In React, register the component in `ReactElementFactory` as shown in the `SurveyComponent.jsx` file.          
    In Angular, register the component in `AngularComponentFactory` as shown in the `progressbar-percentage.component.ts` file.          
    In Vue.js, use [techniques native to this framework](https://vuejs.org/guide/components/registration).

2. Add the progress bar to the survey layout.           
Call the [`addLayoutElement`](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#addLayoutElement) method. It accepts an object whose properties specify the element's `id`, a `container` that determines the element's location, a `component` that renders the element, and `data` to pass as component props. Refer to the method description for more information on these properties.

## Files

### `public/index.html`

```html
<div id="surveyElement" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; min-height: 100%; height:100%"></div>
```

### `src/SurveyComponent.jsx`

```js
import React from "react";
import { Model } from "survey-core";
import { Survey } from "survey-react-ui";
import "survey-core/survey-core.min.css";
import "./index.css";
import { json } from "./json";
import { Serializer } from "survey-core";
import { ReactSurveyElement, ReactElementFactory } from "survey-react-ui";

Serializer.addProperty("survey", "progressTitle");

class PercentageProgressBar extends ReactSurveyElement {
    render() {
        return (
            <div className="sv-progressbar-percentage">
              <div className="sv-progressbar-percentage__title">
                <span>{this.props.model.progressTitle}</span>
              </div>
              <div className="sv-progressbar-percentage__indicator">                    
                {this.props.model.progressValue > 0 && (
                    <div
                        className="sv-progressbar-percentage__value-bar"
                        style={{ width: this.props.model.progressValue + "%" }}
                    ></div>
                 )}
              </div>
              <div className="sv-progressbar-percentage__value">
                <span>{this.props.model.progressValue + "%"}</span>
              </div>
            </div>
        );
    }
}



ReactElementFactory.Instance.registerElement("sv-progressbar-percentage", props => {
    return React.createElement(PercentageProgressBar, props);
});

function SurveyComponent() {
    const survey = new Model(json);
    survey.onComplete.add((sender, options) => {
        console.log(JSON.stringify(sender.data, null, 3));
    });
    survey.addLayoutElement({
        id: "progressbar-percentage",
        component: "sv-progressbar-percentage",
        container: "contentTop",
        data: survey
    });
    
    return (<Survey model={survey} />);
}

export default SurveyComponent;
```

### `src/index.css`

```css
.sv-progressbar-percentage {
    display: flex;
    flex-direction: row;
    gap: 16px;
    line-height: 32px;
    padding: 24px;
    border-radius: 6px;
    box-shadow: var(--sjs2-border-effect-surface-default, 0px 1px 2px 0px rgba(0, 0, 0, 0.15));
    background: var(--sjs2-color-component-panel-default-bg, #fff);
    margin-bottom: 24px;
    justify-content: center;
    align-items: center;
    color: var(--sjs2-color-component-question-default-title, #161616);
}
.sd-root--compact .sv-progressbar-percentage {
    box-shadow: none;
    border: 1px solid var(--sjs2-color-component-input-default-line, #d6d6d6);
}
.sv-progressbar-percentage__title {
    font-size: 20px;
    display: flex;
}

.sv-progressbar-percentage__indicator {
    position: relative;
    display: flex;
    width: 100%;
    max-width: 50%;
    height: 32px;
    box-shadow: var(--sjs2-border-effect-surface-default, 1px 1px 1px 1px rgba(0, 0, 0, 0.15));
    border-radius: 9999px;
    background: var(--sjs2-color-bg-basic-secondary-dim, rgba(243, 243, 243, 1));
    height: 16px;
}

.sv-progressbar-percentage__value-bar {
    position: absolute;
    left: 0;
    top: 0;
    border-radius: 9999px;
    border: 1px solid var(--sjs2-color-project-brand-600, #19b394);
    background: var(--sjs2-color-project-brand-600, #19b394);
    height: 16px;
}

.sv-progressbar-percentage__value {
    font-size: 20px;
    display: flex;    
}

```

### `src/index.js`

```js
import React from "react";
import { createRoot } from "react-dom/client";
import SurveyComponent from "./SurveyComponent";

const root = createRoot(document.getElementById("surveyElement"));
root.render(<SurveyComponent />);
```

### `src/json.js`

```js
export const json = {
  "title": "Customer Satisfaction Survey",
  "showTOC": true,
  "progressTitle": "Survey Progress",
  "progressBarType": "questions",
  "pages": [
    {
      "navigationTitle": "Satisfaction",
      "elements": [
        {
          "type": "matrix",
          "name": "Quality",
          "title": "Please indicate if you agree or disagree with the following statements",
          "columns": [
            {
              "value": 1,
              "text": "Strongly Disagree"
            },
            {
              "value": 2,
              "text": "Disagree"
            },
            {
              "value": 3,
              "text": "Neutral"
            },
            {
              "value": 4,
              "text": "Agree"
            },
            {
              "value": 5,
              "text": "Strongly Agree"
            }
          ],
          "rows": [
            {
              "value": "affordable",
              "text": "Product is affordable"
            },
            {
              "value": "does what it claims",
              "text": "Product does what it claims"
            },
            {
              "value": "better then others",
              "text": "Product is better than other products on the market"
            },
            {
              "value": "easy to use",
              "text": "Product is easy to use"
            }
          ]
        },
        {
          "type": "rating",
          "name": "satisfaction",
          "title": "How satisfied are you with our product?",
          "minRateDescription": "Not Satisfied",
          "maxRateDescription": "Completely satisfied"
        },
        {
          "type": "rating",
          "name": "recommend friends",
          "visibleIf": "{satisfaction} > 3",
          "title": "How likely are you to recommend our product to a friend or co-worker?",
          "minRateDescription": "Will not recommend",
          "maxRateDescription": "I will recommend"
        },
        {
          "type": "comment",
          "name": "suggestions",
          "title": "What would make you more satisfied with our product?",
          "maxLength": 500
        }
      ]
    },
    {
      "navigationTitle": "Pricing",
      "elements": [
        {
          "type": "radiogroup",
          "name": "price to competitors",
          "title": "Compared to our competitors, do you feel our product is",
          "choices": [ "Less expensive", "Priced about the same", "More expensive", "Not sure" ]
        },
        {
          "type": "radiogroup",
          "name": "price",
          "title": "Do you feel our current price is merited by our product?",
          "choices": [ "correct|Yes, the price is about right", "low|No, the price is too low for your product", "high|No, the price is too high for your product" ]
        },
        {
          "type": "multipletext",
          "name": "pricelimit",
          "title": "What is the... ",
          "items": [
            {
              "name": "mostamount",
              "title": "Most amount you would every pay for a product like ours"
            },
            {
              "name": "leastamount",
              "title": "The least amount you would feel comfortable paying"
            }
          ]
        }
      ]
    },
    {
      "navigationTitle": "Contacts",
      "elements": [
        {
          "type": "text",
          "name": "email",
          "title": "Thank you for taking our survey. Your survey is almost complete, please enter your email address in the box below if you wish to participate in our drawing, then press the 'Submit' button."
        }
      ]
    }
  ]
};
```

### `src/theme.js`

```js
export const themeJson = {};
```

### `package.json`

```json
{
  "dependencies": {
    "react": "latest",
    "react-dom": "latest",
    "babel": "latest",
    "survey-core": "latest",
    "survey-react-ui": "latest"
  },
  "devDependencies": {
    "react-scripts": "latest"
  }
}
```

## Other Frameworks

- [Angular](https://surveyjs.io/form-library/examples/progress-bar-with-percentage/angular.md)
- [Vue 3](https://surveyjs.io/form-library/examples/progress-bar-with-percentage/vue3js.md)
- [jQuery](https://surveyjs.io/form-library/examples/progress-bar-with-percentage/jquery.md)
- [Vanilla JS](https://surveyjs.io/form-library/examples/progress-bar-with-percentage/vanillajs.md)
