From webflow to BSS?

Hi there, greetings :slight_smile:

I was wondering if there is some way to bring into BSS sites from a friend that are currently built in Webflow.

A few days ago, while searching these forums I came across some references to a utility someone had put together for this, but it seems it is no longer available (I believe it was a member’s contribution, not a commercial product).

From what I had seen a couple of years ago, code exported from webflow has rather messy and it didn’t look like it could be easily imported into anything, but maybe some things have changed after that…

Any suggestions?

Thank you in advance.

EDIT:

I just saw a video of BSS 6.3 and it’s “import template” feature… maybe I could/should import one page at the time from an exported webflow project?

Could I expect a good success ratio, even if WF outputs not-too-clean code?

You’d also need to make sure you had all the CSS and JS WebFlow produced. If your designs don’t use Bootstrap though, they won’t work being converted for use in Bootstrap Studio. They would need recreated with the framework. It’s worth a shot though.

Hi, thanks for the reply.
I’m not a WF user myself so I had not realized that it’s output might not be bootstrap based at all…
Bummer… I’ll have to check that out I guess.

Any other suggestion will be appreciated.
Regards.

Checked WebFlow’s website, and confirmed they have their own framework so none of the exported designs would work on BSS

If you copy a webflow page html code inside the body and add it as custom code. Add the script below and preview the page. If it looks good copy the source code from the preview and replace the custom code. Then you can convert the custom code to components and remove the script.

here is the script

window.addEventListener(
  'DOMContentLoaded',
  function () {
    const randNum = () => Math.floor(Math.random() * 999999) + 100000;

    // Convert Typography & Content
    const containerElements = document.querySelectorAll('.w-container');
    containerElements.forEach((element) => {
      element.classList.add('container');
      element.classList.remove('w-container');
    });

    const blockquoteElements = document.querySelectorAll('blockquote');
    blockquoteElements.forEach((element) => {
      element.classList.add('blockquote');
    });

    const tableElements = document.querySelectorAll('table');
    tableElements.forEach((element) => {
      element.classList.add('table');
    });

    const figureElements = document.querySelectorAll('.w-richtext-figure-type-image');
    figureElements.forEach((element) => {
      element.classList.add('figure');
      const imgElement = element.querySelector('img');
      imgElement.classList.add('figure-img', 'img-fluid');
      const figCaptionElement = element.querySelector('figcaption');
      figCaptionElement.classList.add('figure-caption');
      figCaptionElement.style.margin = 'auto';
    });

    // Convert Navigation
    const navElements = document.querySelectorAll('.w-nav');
    navElements.forEach((element) => {
      const navToggleId = 'navtt-' + randNum();
      const containerElement = element.querySelector('.container');
      containerElement.firstElementChild.unwrap();
      const brandElement = element.querySelector('.w-nav-brand');
      brandElement.classList.add('navbar-brand');
      brandElement.classList.remove('w-nav-brand');
      const navButtonElement = element.querySelector('.w-nav-button');
      navButtonElement.remove();
      const navToggleButton = document.createElement('button');
      navToggleButton.classList.add('navbar-toggler');
      navToggleButton.type = 'button';
      navToggleButton.setAttribute('data-toggle', 'collapse');
      navToggleButton.setAttribute('data-target', '#' + navToggleId);
      element.appendChild(navToggleButton);
      const iconNavMenu = element.querySelector('.w-icon-nav-menu');
      iconNavMenu.classList.add('navbar-toggler-icon');
      iconNavMenu.classList.remove('w-icon-nav-menu');
      navToggleButton.appendChild(iconNavMenu);
      const dropdownToggleElements = element.querySelectorAll('.w-dropdown-toggle');
      dropdownToggleElements.forEach((dropdownToggleElement) => {
        dropdownToggleElement.classList.add('nav-link', 'dropdown-toggle');
        dropdownToggleElement.classList.remove('w-dropdown-toggle');
        dropdownToggleElement.textContent = dropdownToggleElement.textContent;
      });
      const dropdownElements = element.querySelectorAll('.w-dropdown');
      dropdownElements.forEach((dropdownElement) => {
        const randId = 'navdd-' + randNum();
        const newNavItem = document.createElement('li');
        newNavItem.classList.add('nav-item', 'dropdown', ...dropdownElement.classList);
        newNavItem.setAttribute('id', randId);
        dropdownElement.parentElement.insertAdjacentElement('afterend', newNavItem);
        newNavItem.appendChild(dropdownElement.children[0]);
        const dropdownToggle = newNavItem.querySelector('.dropdown-toggle');
        dropdownToggle.setAttribute('data-toggle', 'dropdown');
        dropdownToggle.setAttribute('id', randId);
        dropdownElement.remove();
      });
      const navMenu = element.querySelector('.w-nav-menu');
      navMenu.classList.add('collapse', 'navbar-collapse');
      navMenu.classList.remove('w-nav-menu');
      navMenu.setAttribute('id', navToggleId);
      element.appendChild(navMenu);
      const navLinks = navMenu.querySelectorAll('.w-nav-link');
      navLinks.forEach((navLink) => {
        navLink.classList.add('nav-link');
        navLink.classList.remove('w-nav-link');
        navLink.setAttribute('href', '#');
        const navItem = document.createElement('li');
        navItem.classList.add('nav-item');
        navItem.appendChild(navLink);
        element.appendChild(navItem);
        if (navLink.classList.contains('w--current')) {
          navItem.classList.add('active');
        }
      });
      const navItems = element.querySelectorAll('.nav-item');
      const navItemList = document.createElement('ul');
      navItemList.classList.add('navbar-nav', 'mr-auto');
      navItems.forEach((navItem) => {
        navItemList.appendChild(navItem);
      });
      element.appendChild(navItemList);
      element.querySelector('.w-nav-overlay').remove();
      element.classList.add('navbar', 'navbar-expand-lg', 'navbar-light', 'bg-light', 'fixed-top');
      element.classList.remove('w-nav');
    });

    // Convert all other dropdowns (not in w-nav)
    const dropdownToggleElements = document.querySelectorAll('.w-dropdown-toggle');
    dropdownToggleElements.forEach((dropdownToggleElement) => {
      dropdownToggleElement.classList.add('btn', 'btn-secondary', 'dropdown-toggle');
      dropdownToggleElement.classList.remove('w-dropdown-toggle');
      dropdownToggleElement.textContent = dropdownToggleElement.textContent;
    });

    const dropdownElements = document.querySelectorAll('.w-dropdown');
    dropdownElements.forEach((dropdownElement) => {
      const randId = 'dd-' + randNum();
      const btnGroup = document.createElement('div');
      btnGroup.classList.add('btn-group', 'dropdown', ...dropdownElement.classList);
      btnGroup.setAttribute('id', randId);
      dropdownElement.parentElement.insertAdjacentElement('afterend', btnGroup);
      btnGroup.appendChild(dropdownElement.children[0]);
      const dropdownToggle = btnGroup.querySelector('.dropdown-toggle');
      dropdownToggle.setAttribute('data-toggle', 'dropdown');
      dropdownToggle.setAttribute('id', randId);
      dropdownElement.remove();
    });

    const dropdownListElements = document.querySelectorAll('.w-dropdown-list');
    dropdownListElements.forEach((dropdownListElement) => {
      dropdownListElement.classList.add('dropdown-menu');
      dropdownListElement.classList.remove('w-dropdown-list');
    });

    const dropdownLinkElements = document.querySelectorAll('.w-dropdown-link');
    dropdownLinkElements.forEach((dropdownLinkElement) => {
      dropdownLinkElement.classList.add('dropdown-item');
      dropdownLinkElement.classList.remove('w-dropdown-link');
    });

    // Convert Forms
    const formLabelElements = document.querySelectorAll('.w-form-label');
    formLabelElements.forEach((formLabelElement) => {
      formLabelElement.classList.add('custom-control-label');
    });

    const labels = document.querySelectorAll('label');
    labels.forEach((label) => {
      let elems = label;
      let elem = label;
      while (elem) {
        elem = elem.nextElementSibling;
        if (elem && !elem.matches('label, button, input:submit, .form-group')) {
          elems = elems.add(elem);
        } else {
          break;
        }
      }
      const formGroup = document.createElement('div');
      formGroup.classList.add('form-group');
      elems.forEach((elem) => {
        formGroup.appendChild(elem);
      });
      label.parentElement.appendChild(formGroup);
    });

    const inputElements = document.querySelectorAll('.w-input');
    inputElements.forEach((inputElement) => {
      inputElement.classList.add('form-control');
      inputElement.classList.remove('w-input');
    });

    const selectElements = document.querySelectorAll('.w-select');
    selectElements.forEach((selectElement) => {
      selectElement.classList.add('custom-select');
      selectElement.classList.remove('w-select');
    });

    const checkboxElements = document.querySelectorAll('.w-checkbox');
    checkboxElements.forEach((checkboxElement) => {
      checkboxElement.classList.add('custom-control', 'custom-checkbox');
      checkboxElement.classList.remove('w-checkbox');
    });

    const radioElements = document.querySelectorAll('.w-radio');
    radioElements.forEach((radioElement) => {
      radioElement.classList.add('custom-control', 'custom-radio');
      radioElement.classList.remove('w-radio');
    });

    const checkboxInputElements = document.querySelectorAll('.w-checkbox-input, .w-radio-input');
    checkboxInputElements.forEach((checkboxInputElement) => {
      checkboxInputElement.classList.add('custom-control-input');
      checkboxInputElement.classList.remove('w-checkbox-input', 'w-radio-input');
    });

    const buttonElements = document.querySelectorAll('.w-button');
    buttonElements.forEach((buttonElement) => {
      buttonElement.classList.add('btn', 'btn-primary');
      buttonElement.classList.remove('w-button');
    });

    const formTextElements = document.querySelectorAll('.form-text');
    formTextElements.forEach((formTextElement) => {
      formTextElement.classList.add('small');
    });

    // Convert Tabs
    const tabMenuElements = document.querySelectorAll('.w-tab-menu');
    tabMenuElements.forEach((tabMenuElement) => {
      tabMenuElement.classList.add('nav', 'nav-tabs');
      tabMenuElement.classList.remove('w-tab-menu');
    });

    const tabLinkElements = document.querySelectorAll('.w-tab-link');
    tabLinkElements.forEach((tabLinkElement) => {
      tabLinkElement.classList.add('nav-link');
      tabLinkElement.classList.remove('w-tab-link');
      const navItem = document.createElement('div');
      navItem.classList.add('nav-item', 'w-inline-block');
      tabLinkElement.parentElement.insertBefore(navItem, tabLinkElement);
      navItem.appendChild(tabLinkElement);
      if (tabLinkElement.classList.contains('w--current')) {
        tabLinkElement.classList.add('active');
      }
    });
  },
  false
);
2 Likes

Great, great, great! I will get into this and report back.

Thanks a lot for your time and help guys!
Cheers.