Creating a Medium Posts Widget Using React — Part 2.
Hi everyone 😀! In this article, I concluded by saying that I had to create a build for the widget so that I can embed it the static files anywhere and I was going to discuss how I did it in the next article being this one. Before I proceed though, I recalled that there is something missing from the previous article. If you have been following through up to the point at which I stopped and ran npm start
, you’ll notice that the arrow buttons of the widget do not work as they should. It is missing something. The bootstrap carousel component I made needed so Jquery code to make it work as it should.
I know it’s probably an anti-pattern from quite a number of the articles and answers I saw when I googled if I using Jquery in React was a great idea but I was trying to get it done as quickly as quickly as I could. I had already seen examples before in which they individual imported the npm Jquery package at the top of the React component so that you could use the $
in Jquery so I decided to do the same.
I had to install it first so I ran npm install jquery
and when it finished installing I imported it at the top of my Widget.js
file like this:
import $ from jquery
Then I added my JQuery code (see code below) in the componentDidMount
function, just below the API fetch.
/*
Carousel
*/
$('#postsCardCarousels').on('slide.bs.carousel', function (e) {
/*
CC 2.0 License Iatek LLC 2018 - Attribution required
*/
var $e = $(e.relatedTarget);
var idx = $e.index();
var itemsPerSlide = 3;
var totalItems = $('.carousel-item').length;
if (idx >= totalItems-(itemsPerSlide-1)) {
var it = itemsPerSlide - (totalItems - idx);
for (var i=0; i<it; i++) {
// append slides to end
if (e.direction === "left") {
$('.carousel-item').eq(i).appendTo('.carousel-inner');
}
else {
$('.carousel-item').eq(0).appendTo('.carousel-inner');
}
}
}
});
When the page reloads, the carousel should work just fine.
Creating The Build for The Widget Component.
Now back to the main agenda for this article: the build for the widget. I wanted to be able to host and serve both the static css and js files using a single <link>
and <script>
tag respectively anywhere and use it to display my widget. In order words, I needed one CSS file and one build js file which would be hosted and the links to each file would be used to achieve what I wanted.
However, using the build script that comes bundled with create-react-app was going to create 3 static js files: main.[hash].chunk.js, [number].[hash].chunk.js and runtime~main.[hash].js.
N.B: Read the create-react-app production build docs to find out what each of these files is and its contents.
This was definitely not what I had in mind and at this point it looked like my plans were failing. However, I believed that if push had come to shove, I would have had to tried concatenating the files to see if that would work. As luck would have it (or rather I knew exactly what to search for), I found this post by Sagiv Ben giat where he was doing something similar. In his case he wanted to show how you can use a widget — a counter-app he created in another react app or with any other external applications.
He had created his own scripts as well as configuration for building, starting and testing the react counter-app widget so I modified them to suit my own use case. I had to install the npm packages he used so I modified my package.json using his as a model, added the relevant dependencies that I didn’t already have and ran npm install
. After installing the dependencies, I then copied the scripts
and config
folders from the counter-app
folder in his repository and added it to mine.
In the config folders, I had to modify the paths.js
file. At the line where he exports appBuild
, I change the name in the resolveApp()
function to what I want the name of my custom build folder to be — widget_dist
. Next, I move to the webpack.config.prod.js
file and change lines containing filename: ‘static/css/react-counter.css’
and filename: ‘static/js/react-counter.js’
to filename: ‘static/css/widget.css’
and filename: ‘static/js/widget.js’
respectively. These lines are responsible for specifying there the optimized build code will be stored. Then lastly in my package.json
file, I changed my start and build commands in scripts
to “start”: “node scripts/start.js”
and “build”: “node scripts/build.js”
respectively. I had to change the start command as well because using the react-scripts start command required a dependency that my newly installed node modules were interfering with.
Running npm run build
generates a new folder in my project called widget_dist
and within that folder I could see my static files in the static folder — widget.css
in the css
folder and widget.js
in the js
folder. I was almost done. I took that folder and hosted it on a site of mine and in my github page, I removed the former embedly medium posts and replaced it with this line of code
<div id="medium-posts-widget" data-medium-rss="https://medium.com/feed/@adamichelllle"></div>
Then at the top of my page, I added a new link tag with the url of my hosted css file filling the href
attribute with the link to my hosted css file
<link rel="stylesheet" href="https://my_host_domain/static/css/widget.css">
I also did likewise for the js file.
<script src="https://my_host_domain/static/js/widget.js"></script>
When I refreshed the page, my widget was active and showing on my github profile page. See what it looks like here:
Here’s the link to the Github repo for this project: Medium Posts Widget.
If you got to this point, yay! Thanks for reading. You can also let me know what you think about this in the comments. Please do share if you liked it. Till next time.
Resources
- Micro Frontends — integrate React with other applications and Frameworks by Sagiv Ben giat.
- React External Integration Starter Repo by Sagiv Ben giat.