# Getting Started With Storybook Without a JavaScript Framework

We all want to use well-documented UI components in our Frontend. With Storybook, you can do that reasonably quickly with React, Angular, Vue, or any other framework. 

But since the documentation lacks clear information about how to set up Storybook without any JavaScript framework, I'm going to write it all down for you because it is possible to use plain HTML & CSS.

---

*Want to learn more about why you should use Storybook, check out "[Why You Should Always Use Storybook When Developing User Interfaces](https://levelup.gitconnected.com/why-you-should-always-use-storybook-when-developing-user-interfaces-4c69b93b2f65)" by [Tyler Hawkins](https://thawkin3.medium.com/).*

---

## Installation

Add Storybook by running the following command in the terminal.

```bash
npx sb init
```

This command will add all the dependencies for Storybook and create initial files so that you can get started right away.

After installation, you will see a question "*Do you want to manually choose a Storybook project type to install?*", for this, you type **yes**.

Second question: "*Please choose a project type from the list*", for this, you type **HTML**.

Now the CLI will set everything up to use Storybook with plain HTML.

Run `npm run storybook` when the installation is finished.

---

## Global setup

When you check your directory, you will see a folder `.storybook`. In this folder, there are two files, `main.js` and `preview.js` . 

In the `main.js` file, you can configure what directory will be checked for `*.stories.js` files (*other file extensions are possible)*. Storybook also has a plugin system called [addons](https://storybook.js.org/docs/html/addons/introduction) which you can add here as well.

In the `preview.js` file, you can add everything that needs to be loaded while previewing your UI components.

For example, add your global CSS file or icon font to have it available in all the components.

---

## Example story file for plain HTML

In the stories folder, you will find the files `Button.stories.js`. It looks like this.

```jsx
import { createButton } from './Button';

export default {
  title: 'Example/Button',
  argTypes: {
    label: { control: 'text' },
    primary: { control: 'boolean' },
    backgroundColor: { control: 'color' },
    size: {
      control: { type: 'select', options: ['small', 'medium', 'large'] },
    },
    onClick: { action: 'onClick' },
  },
};

const Template = ({ label, ...args }) => {
  // You can either use a function to create DOM elements or use a plain html string!
  // return `<div>${label}</div>`;
  return createButton({ label, ...args });
};

export const Primary = Template.bind({});
Primary.args = {
  primary: true,
  label: 'Button',
};

export const Secondary = Template.bind({});
Secondary.args = {
  label: 'Button',
};

export const Large = Template.bind({});
Large.args = {
  size: 'large',
  label: 'Button',
};

export const Small = Template.bind({});
Small.args = {
  size: 'small',
  label: 'Button',
};
```

This is an excellent example of how a story file looks like. The code in `Button.js` will create a `<button>` element.

```jsx
import './button.css';

export const createButton = ({
  primary = false,
  size = 'medium',
  backgroundColor,
  label,
  onClick,
}) => {
  const btn = document.createElement('button');
  btn.type = 'button';
  btn.innerText = label;
  btn.addEventListener('click', onClick);

  const mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary';
  btn.className = ['storybook-button', `storybook-button--${size}`, mode].join(' ');

  btn.style.backgroundColor = backgroundColor;

  return btn;
};
```

Even though it looks good and clear, the way the `createButton` is creating a `<button>` tag doesn't let us generate a clear code example to copy and paste (*I will show you* 😉). So we're going to do it a bit differently.

---

## Plain HTML story with code example

To make this work, we need a Storybook addon. Run the code below to install it.

```jsx
npm i @storybook/addon-storysource
```

 After installation, add it to the `.storybook/main.js` file like below.

```jsx
module.exports = {
  "stories": [
    "../stories/**/*.stories.mdx",
    "../stories/**/*.stories.@(js|jsx|ts|tsx)"
  ],
  "addons": [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-storysource"
  ]
}
```

Create a folder `helpers` in the stories folder. In that folder, create a file, `code-example.js`. In this file, we will create a helper function that generates data for our code example.

```jsx
function addCodeExample(component, templateConfig) {
  if(!component || !templateConfig) return

  component.parameters = {
    docs: {
      source: {
        code: templateConfig({
          label: component?.args?.label,
          className: component?.args?.className
        })
      }
    }
  }

  return component
}

export { addCodeExample }
```

In this function, we take the `component` and the `templateConfig` as parameters. These parameters are going to provide us with information from the components themselves.

For this example, I will minimize the length of the `Button.stories.js` by adding only one example of a button. So copy-paste the code below.

```jsx
export default {
  title: 'Example/Button',
  argTypes: {
    label: { control: 'text' },
    className: { control: 'text' }
  },
};

const Template = ({ label, className }) => {
  return `<button class="${className}">${label}</button>`;
};

export const Primary = Template.bind({});
Primary.args = {
  label: 'Button',
  className: 'button-primary',
};
```

If you check the button component in Storybook, your code example will not be ready to copy-paste yet.


![1_ixLk0cAXwsXiLxtIiG2RDA.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1629443201197/uXAh83HAaR.png)

By using the function to generate that example, you will see the difference.

```jsx
import { addCodeExample } from './helpers/code-example'

export default {
  title: 'Example/Button',
  argTypes: {
    label: { control: 'text' },
    className: { control: 'text' }
  },
};

const Template = ({ label, className }) => {
  return `<button class="${className}">${label}</button>`;
};

export const Primary = Template.bind({});
Primary.args = {
  label: 'Button',
  className: 'button-primary',
};
addCodeExample(Primary, Template)
```

Here you can see that I added `Primary` as the first parameter and `Template` to the next. This will generate the simple HTML code you can copy and paste.


![1__sXoxiGFDBuGPr1lQgnZYQ.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1629443227929/DNWU0QzoSI.png)

---

## Conclusion

Now that you know how to use Storybook with plain HTML and CSS, you can create your UI components much more effectively!

Storybook is a great tool to use in any web application. I’m super happy with it! If you want, check out  [their project on GitHub](https://github.com/storybookjs/storybook)  and show some support!

In what kind of application or architecture are you using or planning to use Storybook? Please let me know.

---

## Thanks!
![hashnode-footer.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1629789655319/nBF6anHH4w.png)
*I hope you learned something new or are inspired to create something new after reading this story! 🤗 If so, consider subscribing via email (scroll to the top of this page) or follow me here on Hashnode.
*

> Did you know that you can create a [Developer blog like this one, yourself](https://hashnode.com/@devbyrayray/joinme)? It's entirely for free. 👍💰🎉🥳🔥

*If I left you with questions or something to say as a response, scroll down and type me a message. Please send me a [DM on Twitter @DevByRayRay](https://twitter.com/@devbyrayray) when you want to keep it private. My DM's are always open 😁*

