Thursday, April 30, 2026

Building a Country Higher or Lower Game

I Built a Country Higher or Lower Game with JavaScript and Country Data

I recently built a small browser game called Country Higher or Lower. The idea is simple: the game shows two countries, one population is visible, and the player has to guess whether the other country has a higher or lower population.

This project is based on a similar idea to my Pokémon Higher or Lower game, but it feels different in practice. Pokémon stats are fun if you know Pokémon, but countries are much more general. Almost everyone understands the concept immediately. You see two countries, compare them, and make a guess.

That is why I think this version works well as a small browser game. It is clean, fast to play, and easy to understand. The player does not need to read a long explanation before starting. The game can be played directly in the browser, and it also works on mobile.

You can play the game here: Country Higher or Lower Game

The source code is available here: Country Higher or Lower on GitHub

The basic idea

The game shows two countries. One country has its population shown, while the other country has its population hidden. The player chooses higher or lower. If the answer is correct, the score increases and the game continues. If the answer is wrong, the round ends and the player can restart.

That is the whole game loop, but the data makes it interesting. Country population is not always easy to guess. Some countries are very large on a map but have relatively small populations. Other countries are geographically smaller but have far more people living there.

That makes the game more interesting than just recognizing flags or country names. It becomes a small guessing game about geography, population, and how misleading country size can be.

Using REST Countries for the data

For the country data, I used REST Countries. REST Countries describes itself as a RESTful API for getting information about countries. The official website lists v3.1 as the current version, with v4 currently in preview. It also says the API covers more than 250 countries and is open source and free to use.

For my game, I only needed a small part of that data. The important values were the country name, the population, and the country code. The country name is shown to the player, the population is used for the comparison, and the country code becomes useful later for displaying the flag.

I did not want the game to call the API every time someone plays a round. That would be unnecessary for this kind of project. Country population data does not need to be fetched again and again during gameplay.

Instead, I wrote a JSON builder. The builder fetches the country data once, extracts the useful values, and creates a local JSON file. The actual game then reads from that local JSON file.

This keeps the game simple and fast. It also works well for a static GitHub Pages project because the game does not depend on live API requests while someone is playing.

Why I did not use live API calls during gameplay

Using an API live can be useful when the data changes constantly or when the user needs the newest possible result. But this game does not need that. For a small higher-or-lower game, it is enough to prepare the country dataset once and use it locally.

This is similar to what I did with my Pokémon Higher or Lower project. At first, using live API requests feels like the most direct solution. But once the project becomes a game, repeated requests can become unnecessary.

A local JSON file is a cleaner solution here. The game loads the prepared data, picks countries from it, and compares their populations. The API is still useful, but it is used as a data source during the build process instead of being called during every game session.

The flag problem I did not expect

One problem I did not expect was how annoying country flags can be in a browser project. At first, I wanted to use flag emojis. That felt like the smartest and most efficient solution. I would not have to download images, store image files, or load a separate flag service. I could simply display a flag as text.

But then I tested it and noticed a problem. Flag emojis are not displayed reliably on Windows. On many Windows systems, country flag emojis do not appear as actual flags. Instead, they appear as two regional indicator letters. So instead of seeing a German flag, French flag, or Japanese flag, the user may only see something like DE, FR, or JP.

This happens because emoji rendering depends heavily on the operating system and the browser. On Windows, the Segoe UI Emoji font does not include country flag emoji support. A web developer writeup by Nolan Lawson explains that Microsoft’s emoji font does not have country flags on Windows 10 or Windows 11, so Chrome on Windows can show country codes instead of actual flag images. A Stack Overflow discussion about flag emojis also points out that Windows users often need a separate font, image replacement, or another workaround if proper flag display is important.

That was a problem for this project. For a normal text article, maybe this would not matter much. For a country guessing game, it matters a lot. If some users see flags and other users only see two-letter codes, the game feels inconsistent.

This is one of those problems that only appears once you actually build something. I thought emojis would be a clean solution, but the real browser and operating system behavior made them unreliable. So I decided not to use emoji flags in the game.

Why I used FlagCDN instead

After dropping the emoji idea, I needed another way to display country flags. One option would have been to download and store flag images directly in the project. But that did not feel like the best solution. It would make the project larger, and it would also raise the question of where the images come from and whether they are okay to use.

The better solution was to use FlagCDN. FlagCDN describes itself as a free flag API and CDN service. Its website says it includes all 254 country flags and provides them in formats such as PNG, WebP, SVG, and JPEG.

This worked very well with the structure I already had. My JSON file already contained country codes from the REST Countries data. FlagCDN uses country-code-based URLs. That means the game can take the country code and generate the correct flag image URL.

This made the final solution much cleaner. REST Countries gives me the country data I need for the game. FlagCDN gives me reliable flag images. The country code connects both systems.

I later realized that REST Countries also has flag-related fields. But that was not the original path I took. My first plan was to use emoji flags. When that did not work reliably on Windows, I looked for a solution that could use the country codes I already had in my JSON file. That is how I ended up using FlagCDN.

Why this solution felt clean

The part I like about this project is that the final structure is simple. The game does not store hundreds of flag images. It does not depend on flag emojis working correctly across every operating system. It also does not send unnecessary API requests while the user is playing.

The JSON builder prepares the data. The game reads the local JSON file. The country code is used to load the correct flag image. The player only sees the clean result: two countries, two flags, one simple choice.

That is the kind of solution I like in small web projects. It is not overengineered, but it solves the real problem.

What I learned from this project

The biggest lesson from this project was that the data source is only part of the work. Getting country data was not the hardest part. The more interesting problem was turning that data into a game that works reliably in the browser.

The flag issue is a good example. At first, emojis looked like the easiest solution. But once I tested them across systems, they were not reliable enough. Using FlagCDN with country codes ended up being a much better solution.

I also learned again that local JSON files are very useful for small static projects. You can still use an API during development, but the final game does not always need to call the API live. Sometimes the better structure is to fetch the data once, clean it, and let the game use a prepared dataset.

This project is simple, but it connects several useful web development ideas. It uses API data, a JSON builder, local data loading, generated image URLs, JavaScript game logic, and static hosting. None of these things are huge on their own, but together they create a complete little browser game.

Related projects

This game is connected to a few of my other projects and articles. If you want to try the earlier version of this idea, you can play my Pokémon Higher or Lower game here: Play Pokémon Higher or Lower

I also wrote a longer article about using APIs and local JSON files in browser games: How to Use APIs in a Web Game with JSON Optimization

You can find more of my projects here: View my projects

Conclusion

Country Higher or Lower started as another version of my Pokémon Higher or Lower idea, but it became its own useful project. Countries are more general than Pokémon stats, so the game is easier for more people to understand. The topic is simple, but the implementation still led to interesting technical problems.

The most surprising problem was the flag display. I expected emojis to be an easy solution, but they were not reliable enough on Windows. Using FlagCDN with country codes turned out to be cleaner and more dependable.

For me, this is exactly why small projects are useful. You start with a simple idea, but while building it, you run into real problems that teach you something. In this case, I learned more about APIs, JSON files, country codes, flag images, emoji rendering, and browser differences.

That is what makes these projects worth building. They are not only small games. They are also a way to learn how the web actually behaves.

Sources and credits

Country data is based on REST Countries: REST Countries

Flag images are loaded through FlagCDN: FlagCDN

For more background on the flag emoji issue on Windows and in browsers, these explanations were useful: The struggle of using native emoji on the web and Flag Emojis not rendering

This project is created for educational and entertainment purposes. It is not affiliated with REST Countries or FlagCDN.

Friday, April 24, 2026

How to Embed a GitHub Pages Project in Blogger

How to Embed a GitHub Pages Project in Blogger

One of the most useful things I learned while building small web projects is that you can host a project on GitHub Pages and then embed it directly into a Blogger post or page.

This is especially helpful if you are making small tools, browser games, JavaScript experiments, generators, calculators, or interactive pages. Instead of only writing about the project, you can let people try it directly on your blog.

For example, I use this workflow for some of my own web tools. I build the project with HTML, CSS, and JavaScript, publish it with GitHub Pages, and then place it inside a Blogger page using a simple iframe.

What you need

To embed a GitHub Pages project in Blogger, you need three things:

  • A working GitHub Pages project
  • A Blogger post or Blogger page
  • A little bit of HTML knowledge

You do not need a complex setup. The main idea is simple: GitHub Pages hosts the actual project, and Blogger displays it inside your blog using an iframe.

What is an iframe?

An iframe is an HTML element that lets you display another webpage inside your current page. You can think of it like a small window inside your blog post.

The iframe does not copy the project into Blogger. The project still runs on GitHub Pages. Blogger only shows it inside the post or page.

A basic iframe looks like this:

<iframe 
  src="https://your-username.github.io/your-project/" 
  width="100%" 
  height="600" 
  style="border: none;">
</iframe>

The most important part is the src attribute. This is where you put the link to your published GitHub Pages project.

Do not use the normal GitHub repository link

One common mistake is using the normal GitHub repository URL. That will usually look something like this:

https://github.com/your-username/your-project

That is not the link you want to embed. That link points to the source code repository, not the actual published website.

For the iframe, you need the GitHub Pages URL. That usually looks like this:

https://your-username.github.io/your-project/

That is the public website version of your project. If you open that link in your browser and your project loads like a normal website, then it is the right link to use inside the iframe.

How to enable GitHub Pages

Before you can embed the project, you need to publish it with GitHub Pages.

In your GitHub repository, go to:

Settings → Pages

Then look for the GitHub Pages build and deployment settings. In many simple projects, you can choose to deploy from a branch, usually the main branch, and select the root folder or the /docs folder depending on where your project files are.

For a simple HTML, CSS, and JavaScript project, your project usually needs an index.html file. That file is the entry point of the website. When someone opens your GitHub Pages URL, GitHub Pages loads that file first.

After you save the GitHub Pages settings, GitHub will publish your project. Sometimes it takes a few minutes before the page is available.

Embedding the project in Blogger

Once your GitHub Pages project is online, go to Blogger and create a new post or page.

Then switch from Compose view to HTML view. This is important because the iframe is HTML code.

Now paste this code where you want the project to appear:

<div style="margin: 20px 0;">
  <iframe 
    src="https://your-username.github.io/your-project/" 
    width="100%" 
    height="650" 
    style="border: none; max-width: 100%;" 
    loading="lazy">
  </iframe>
</div>

Then replace the example URL with your own GitHub Pages link.

What the iframe code does

Here is the same code again:

<iframe 
  src="https://your-username.github.io/your-project/" 
  width="100%" 
  height="650" 
  style="border: none; max-width: 100%;" 
  loading="lazy">
</iframe>

The src value is the page you want to embed. This should be your GitHub Pages URL.

The width="100%" part makes the iframe fill the available width of the blog post. This is usually better than using a fixed pixel width because it works better on different screen sizes.

The height="650" part controls how tall the embedded project appears. If your project is small, you can use a lower number. If your game or tool needs more vertical space, you can increase it.

The style="border: none;" part removes the default iframe border. Without this, the embedded project may have an old-looking frame around it.

The loading="lazy" part tells the browser that it can load the iframe later, when the visitor scrolls near it. This can help the page feel lighter, especially if the embedded project is not visible immediately.

A cleaner Blogger embed example

For Blogger, I like wrapping the iframe inside a div. This makes it easier to add spacing around the project.

<div style="margin: 24px 0; text-align: center;">
  <iframe 
    src="https://your-username.github.io/your-project/" 
    width="100%" 
    height="700" 
    style="border: 0; max-width: 100%;" 
    loading="lazy">
  </iframe>
</div>

This version gives the embedded project some space above and below, which usually looks better inside a blog article.

Optional: Add a button below the iframe

Sometimes it is useful to add a direct link below the embedded project. That way, if the iframe does not load properly on someone’s browser, they can still open the tool directly.

<div style="margin: 20px 0; text-align: center;">
  <a 
    href="https://your-username.github.io/your-project/" 
    target="_blank" 
    style="background: #333; color: white; padding: 12px 18px; border-radius: 6px; text-decoration: none; font-weight: bold;">
    Open Project in New Tab
  </a>
</div>

I think this is a good idea because it gives visitors a backup option. Some embedded projects may feel better in a full browser tab, especially games.

Common problems

The iframe is too small

If your project looks cut off, increase the height value:

height="800"

You can test different values until the project fits nicely.

The project does not load

First, open the GitHub Pages URL directly in your browser. If it does not work there, the problem is not Blogger. The project itself is probably not published correctly yet.

Also make sure you are using the GitHub Pages link, not the GitHub repository link.

The project works on desktop but feels bad on mobile

This usually means the project itself needs better responsive design. Blogger can show the iframe, but the project inside the iframe still needs to be mobile-friendly.

For small tools and games, it helps to design the project with flexible widths and simple layouts.

The iframe has weird spacing

You can adjust the wrapper div:

<div style="margin: 20px 0;">
  iframe goes here
</div>

The first value controls the top and bottom spacing. The second value controls left and right spacing.

Why this workflow is useful

I like this workflow because it connects coding projects with blogging. A normal blog post can explain the idea, the process, and what I learned. The embedded GitHub Pages project lets the reader actually try it.

This is much better than only showing screenshots. Screenshots are useful, but interactive projects make the post feel more alive.

It also helps organize small projects. Instead of having random GitHub repositories that nobody sees, you can turn each project into a blog post, a tool page, or both.

Example workflow

A simple workflow could look like this:

  1. Build a small HTML, CSS, and JavaScript project.
  2. Publish it with GitHub Pages.
  3. Create a Blogger page for the tool.
  4. Embed the GitHub Pages project with an iframe.
  5. Write a blog post explaining how and why you built it.
  6. Link the blog post and tool page together.

That last step is important. The tool page gives people a place to use the project, and the blog post gives search engines and readers more context.

Final thoughts

Embedding GitHub Pages projects into Blogger is a simple way to turn small coding experiments into real interactive content.

You only need a published GitHub Pages project, a Blogger post or page, and a small iframe snippet. Once you understand how the iframe works, you can reuse the same structure for games, generators, tools, calculators, and other small web projects.

For me, this makes Blogger much more useful. It is not just a place for writing. It can also become a small hub for projects, experiments, and interactive tools.

Related posts and tools

Wednesday, April 1, 2026

How to Use APIs in a Web Game (Pokémon Example with JSON Optimization)

I built a simple browser game where you compare two Pokémon and guess which one has higher total stats. The idea is simple: you see two Pokémon, choose the one you think is stronger, and then the game checks the real data.

The project started as a small JavaScript game using the PokéAPI. At first, the game fetched new Pokémon data directly from the API during gameplay. That worked, but it also created a scaling problem. Every round needed new API requests, and every player would create more requests.

To fix that, I changed the project so the game uses a local JSON file instead. The API is still used, but only once during the data-building step. During gameplay, the game loads the prepared JSON file and runs almost completely locally in the browser.


Overview

At the beginning, I used the most direct approach. Every time the user started a new round, the game sent fetch requests to the API. I had already used this pattern in an earlier project, a random Pokémon generator, so it felt natural to reuse it.

For a simple random generator, this works fine. One button click means one request, and the result appears on the page. But a game is different. A higher or lower game needs repeated rounds, and each round needs two Pokémon. Ten rounds can easily mean twenty API requests from one player.

This is a common beginner mistake when working with APIs. Just because you can fetch data on every interaction does not always mean you should. Many APIs have rate limits, require tokens, or cost money at scale. Even when an API is free, it is still better practice to reduce unnecessary requests.

I chose the PokéAPI because it is open, free to use, and does not require authentication. That makes it perfect for learning and experimenting. But even with a free API, the scaling problem is still worth understanding.

In this post, I explain how I built the game, what problems appeared when using live API requests, and how switching to a local JSON file made the project faster, simpler, and easier to expand.


The earlier project: Random Pokémon Generator

Before building the higher or lower game, I had already worked on a smaller project: a random Pokémon generator. This project is very simple. You click a button, and it shows a random Pokémon with its name and sprite.

The generator works by creating a random Pokémon ID in JavaScript. The script then sends a request to the PokéAPI using that ID. From the response, it only takes the data needed for the project: the Pokémon name and sprite image.

That data is then displayed on the page. The logic is small, but it teaches an important idea: a website can request real external data and use it to update the page.

random ID → API request → Pokémon data → update the page

This approach is completely fine for a small tool. One click usually means one request, and the user gets a result immediately.

I also wrote a separate post about that generator and made the tool available here:

Try the Random Pokémon Generator Read the Generator Article

The random generator gave me the starting point for the higher or lower game. I reused the same basic idea, but once I turned it into an actual game loop, the weaknesses of repeated live API requests became much more obvious.


The first approach: fetching data per round

When I started building the Pokémon Higher or Lower game, I first used the same approach as the random generator. The game selected two random Pokémon IDs, fetched both Pokémon from the API, extracted their names, sprite URLs, and stats, and then calculated the total stat value.

After that, the player chose which Pokémon they thought had the higher total. The game checked the answer, updated the score, and then started the next round.

The early version worked like this:

start round → fetch Pokémon A → fetch Pokémon B → compare stats → player guesses → next round

At first, this felt fine. The game worked, the logic was easy to understand, and the API gave me the exact data I needed. But the problem becomes clear when you count the requests.

One round already needs two API calls. If one player plays ten rounds, that is around twenty requests. If several people play the game, the number grows quickly. The more successful the game becomes, the more requests it creates.


Why repeated API requests became a problem

The main issue was that the game depended on live API requests during gameplay. Every new round needed fresh data from an external service.

That creates three practical problems.

1. The game becomes slower

Even if the API responds quickly, there is still a delay. The browser has to send the request, wait for the response, parse the JSON, and then update the game. In a game with many rounds, even small delays can make the experience feel less responsive.

2. The game depends on the API being available

If the API is slow, unavailable, or temporarily blocked, the game stops working properly. That is not ideal for a browser game, especially when the data does not actually need to be live.

3. The request count scales with the number of players

This is the biggest problem. If every player creates API requests during every round, the number of requests increases with traffic. For a learning project, this may not matter much, but it is still a bad pattern to rely on if the data can be prepared in advance.

One possible improvement would be browser caching. If a Pokémon was already fetched once, the game could store it and reuse it. That would reduce repeated requests for the same Pokémon.

But caching only partially solves the issue. There are over 1000 Pokémon, and in a short play session the chance of randomly getting the same Pokémon again is not always high. The game would still depend on live API requests for new entries.

So I decided to solve the problem differently. Instead of fetching Pokémon during gameplay, I moved the required data into a local JSON file.


The solution: using a local JSON file

The better solution was to separate the data-building step from the gameplay step.

Instead of asking the API for Pokémon during every round, I wrote a separate script that fetches all required Pokémon data once and saves it into a local JSON file.

That script goes through the Pokémon list, fetches each Pokémon from the PokéAPI, extracts the fields I need, and stores them in a smaller format. For this game, I only needed a few things:

  • Pokémon ID
  • Pokémon name
  • Sprite image URL
  • Individual stats
  • Total stat value

The total stat value can be calculated during the build step by adding the individual stats together. That way, the game itself does not need to do unnecessary work every time a round starts.

build script → fetch all Pokémon once → save useful fields → load JSON in the game

One important detail is how the images are handled. The JSON file does not store the actual image data. It only stores the URL to each Pokémon sprite. This keeps the JSON file much smaller and easier to load.

If the JSON file stored image data directly, it would become much larger and slower. For this project, sprite URLs are enough.

After the JSON file is created, the game no longer needs to call the API during gameplay. It loads the local JSON file once, stores the data in memory, and then selects random Pokémon from that local dataset.

The gameplay version then becomes much simpler:

load JSON once → pick two random entries → compare total stats → next round

This is a much better structure for this kind of project because Pokémon data does not need to be live. It does not change every minute like weather data, stock prices, or live sports scores.

If new Pokémon are added later, the JSON file can simply be rebuilt. That could be done manually, or it could be automated with something like a GitHub Action.


Performance and reliability improvements

The JSON approach improves the game in several ways.

Faster rounds

When the game used live API requests, every round depended on network speed. With local JSON data, the round can start almost instantly after the initial data load.

Fewer external dependencies

The game no longer depends on the PokéAPI being available during gameplay. If the API is slow or temporarily unavailable, the game can still work because the needed data is already stored locally.

Lower request count

During gameplay, the number of API requests is reduced to zero. The API is only used during the data-building process.

More consistent user experience

Every player uses the same local dataset. That means the game feels more consistent because each round no longer depends on external response times.

This shows an important principle when working with APIs: live requests are useful, but they should be used carefully. If the data does not need to change constantly, it is often better to load prepared data once and reuse it.


Why the JSON structure is easier to expand

Another advantage of the JSON approach is that the project becomes easier to extend.

Right now, the game compares total stats. But because the data is already stored locally, it would be easy to add more game modes later.

For example, the game could compare:

  • HP
  • Attack
  • Defense
  • Speed
  • Generation
  • Legendary status

It would also be possible to add filters, such as only showing Pokémon from a specific generation, only legendary Pokémon, or only final evolutions.

With live API requests, every new feature could require more request logic and more waiting. With local JSON data, the game already has the information available and can use it immediately.

That is why this project became more than just a small Pokémon game. It became a useful example of how preparing data in advance can make a web project faster, cleaner, and easier to expand.


Conclusion

The first version of the game worked, but it was not the best structure. Fetching Pokémon from the API during every round made the game depend too much on live requests.

Moving the required data into a local JSON file made the game faster, more reliable, and easier to expand. The API is still useful, but it is used at the right time: during the build process, not during every player interaction.

This is the main lesson from the project. APIs are powerful, but good API usage is not only about knowing how to fetch data. It is also about knowing when not to fetch data.

For static or rarely changing data, a prepared JSON file can be a better choice than repeated live requests. For real-time data, live API calls are still necessary. The important part is choosing the right structure for the type of data you are using.

Try the project

You can play the finished browser game here:

Play the Pokémon Higher or Lower Game

You can also view the source code on GitHub:

View Source Code on GitHub

Related projects

Disclaimer: This project is not affiliated with Pokémon, Nintendo, Game Freak, Creatures Inc., or any related companies. It is a personal fan-made project created for educational purposes only.

Stop Making Platformers First

A lot of indie games start as prototypes. You make something small, it feels fun, someone plays it, and suddenly the idea appears: maybe ...