Embeddable JavaScript widgets
How to create a GitHub gist-like embeddable widget using Rails
May 22, 2022
2 min read
GitHub Gists example
GitHub Gists are great and easy to share. Simply paste their embed code onto any page.
<!-- Embed code -->
<script src="https://gist.github.com/BrianSigafoos/f0fe5e6417b0acf70ffe1bc6b6498796.js"></script>
The response from that script simply does 2 things using document.write():
- Add a stylesheet
- Add the HTML tags to render the gist content.
// Endpoint Response to .js code above
document.write(
'<link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-5687a589e344.css" />'
)
document.write(
'<div id="gist74791356" class="gist">\n <div class="gist-file" translate="no">...</div></div></ div>\n'
)
Recreating it in Rails
The code to embed the widget is simple:
<div class="demoapp demoapp-widget">
<script src="http://lvh.me:3000/widgets/mKVEFN.js"></script>
<p>Widget created with <a href="https://github.com/BrianSigafoos/docker-rails-webpacker-app">Docker Rails Demo App</a> by Brian</p>
</div>
And here is a widget rendered below. Note: this only works locally for now via this repo.
How it works
- Add a new route
resources :widgets, only: :show - Add the new WidgetsController with
skip_before_action :verify_authenticity_tokenandlayout falsewith a show.js.erb like this - Add the
rack-corsgem to allow CORS with a config/initializers/cors.rb like this - Add the widget CSS via a new widget.scss like this
- You’ll want to scope the CSS to only your app
:where(.demoapp) { ... }, for example
- You’ll want to scope the CSS to only your app
- Add code to generate the copyable widget snippet
- Add code to preview the widget snippet in your app, without any CSS on that page
- Use something like Hugo (that powers this blog) to locally create a page and then embed the snippet. This will confirm CORS is set up correctly as the widget is called from the local Hugo-served page and to the local Rails endpoint.
Read more posts like this in the
Software Engineering Toolbox
collection.