buttons/github-buttons

Buttons are not styled when page loads

wcarhart opened this issue ยท 5 comments

Hi there, super cool project.

I'm trying to use your buttons on my deployed documentation site: https://willcarhart.dev/docs/koi. Unfortunately, I can't get them to load properly.

I am using them in a div to center them, like so:

<div align="center">
  <a class="github-button ghbns" href="https://github.com/wcarhart/koi/subscription" data-icon="octicon-eye" data-size="large" data-show-count="true" aria-label="Watch wcarhart/koi on GitHub">Watch</a>
  <a class="github-button ghbns" href="https://github.com/wcarhart/koi" data-icon="octicon-star" data-size="large" data-show-count="true" aria-label="Star wcarhart/koi on GitHub">Star</a>
  <a class="github-button ghbns" href="https://github.com/wcarhart/koi/fork" data-icon="octicon-repo-forked" data-size="large" data-show-count="true" aria-label="Fork wcarhart/koi on GitHub">Fork</a>
  <a class="github-button ghbns" href="https://github.com/wcarhart" data-size="large" data-show-count="true" aria-label="Follow @wcarhart on GitHub">Follow @wcarhart</a>
</div>

Where the only additional styling I've applied is:

.ghbns {
	padding-left: 1rem;
	padding-right: 1rem;
}

I see in my browser that https://buttons.github.io/buttons.js is loading, but I don't see the buttons being styled properly. Network graph:
image

Web page:
image

I have tested in Chrome, Safari, and Brave, with localhost and on the live deployed site. I have also tried without the additional CSS styling, and loading the script without async and defer. Have you ever had this occur before? If so, do you have any hints?

ntkme commented

The problem is that you're using a single page web app.

When DOMContentLoaded event happens, your web app is not fully loaded and mounted yet. The buttons.js script kicks in before your app is mounted. At that moment, <a class="github-button"> is not in the DOM yet, which is why it does not work.

In general, for it to work in dynamic web using Vue / React / etc., there are two ways:

  1. Put the tag outside of app root mount element and use the buttons.js script. This way the tag will exist on DOMContentLoaded. - This will not work for the layout you want to achieve.
  2. Programmatically invokes render method after app is mounted. Note there are components for Vue / React which does that for you.

On a side note, if you want to add margin, add class to <a class="github-button ghbns"> will not work, instead, wrap each button with a span like <span class="ghbns"><a class="github-button"></span>.

Ah, thanks for the help. I'm not actually managing the web app myself, I'm using a static site generator called Docsify. I'm not entirely sure how to go about this (I don't have a lot of experience with Vue), but I can mount a DOM element: https://docsify.js.org/#/configuration?id=el

Do you know how I would add the button using Docsify? If it's too much work, it's not a big issue.

ntkme commented

I never used or tested this on docsify. However, by reading the documentation I think you can probably use external script plugin. With this plugin, you would need to add buttons.js script to .md file that contains the button rather than the index.html. That may just work.

Now, the proper way to do it is to write a docsify plugin that import this library and run its render function on Docsify.dom.findAll('a.github-button'), it should be very similar to external script plugin (source code) in general structure.

ntkme commented

I don't have time to test it, but something like this should work (make sure you use rollup or webpack to take care of the import and generate a bundled script).

import { render } from 'github-buttons'

function handleGitHubButtons() {
  const container = Docsify.dom.getNode('#main')
  const buttons = Docsify.dom.findAll(container, 'a.github-button')

  for (let i = buttons.length; i--; ) {
    const button = buttons[i];
    render(button, function (el) {
      button.parentNode.replaceChild(el, button)
    })
  }
}

const install = function(hook) {
  hook.doneEach(handleGitHubButtons)
}

window.$docsify.plugins = [].concat(install, window.$docsify.plugins)

Thanks for the advice, I will put that in my backlog to work on. In the meantime, I used a hacky solution to append the script to the DOM after it's loaded:

// load GH buttons once docsify has rendered the page
document.addEventListener("DOMContentLoaded", theDomHasLoaded, false);

function theDomHasLoaded(e) {
  console.log('DOM has loaded, appending GH buttons script')
  let newScript = document.createElement('script');
  newScript.src = 'https://buttons.github.io/buttons.js'
  document.head.appendChild(newScript);
  console.log('Appended GH buttons script to DOM')
}

Thanks for the help! Started sponsoring you for a bit, really appreciate it