How does your own star rating differ from those offered by online services?
Your own rating has the following differences:
Control: You have complete control over the design, functionality, and rules. Online services often impose restrictions on customization.
Free: You can use free databases like Firebase, unlike many paid services.
Independence: Your rating is integrated into the Blogger template and remains your project, without being tied to external platforms.
However, it is important to keep in mind that developing your own rating takes time and technical knowledge.
What are the pros and cons of developing a star rating for Blogger?
Pros: ✔️ Full design customization. ✔️ Dynamic rating data update. ✔️ No need to pay for use. ✔️ No ad units or branding.
Cons: ❌ Requires basic programming skills. ❌ Time to set up (unlike ready-made widgets). ❌ Need to connect to a database.

Setting up Firebase for Star Rating 🔧
How to get JavaScript code to connect to Firebase?
Firebase is a free cloud database that is great for storing ratings data. Here is a step-by-step guide to getting the code:
1. Sign up for Firebase
Go to the Firebase Console.
Log in using your Google account.
2. Create a new project
Click the “Add Project” button and come up with a name for your project (for example, rating-system).
Follow the setup instructions. You can leave Google Analytics turned off if you don't plan to use it.
3. Get project configuration
After creating a project, go to the “Project Settings” section.
In the “General Settings” menu, find the “Firebase Configuration” block.
Copy the configuration object containing the apiKey, authDomain, databaseURL, and other parameters.
Firebase Configuration Example for Star Rating
const firebaseConfig = { apiKey: "YOUR_API_KEY", authDomain: "YOUR_PROJECT_ID.firebaseapp.com", projectId: "YOUR_PROJECT_ID", databaseURL: "https://YOUR_PROJECT_ID.firebaseio.com", storageBucket: "YOUR_PROJECT_ID.appspot.com", messagingSenderId: "YOUR_SENDER_ID", appId: "YOUR_APP_ID" };
4. Connect Firebase to your Blogger project
Add two Firebase scripts to your Blogger HTML template:
<script src="https://www.gstatic.com/firebasejs/9.6.1/firebase-app.js"></script> <script src="https://www.gstatic.com/firebasejs/9.6.1/firebase-database.js"></script>
5. Initialize Firebase
Add the initialization JavaScript code to your project:
if (!firebase.apps.length) { firebase.initializeApp(firebaseConfig); } const database = firebase.database();
What rules are needed for the Firebase database?
To ensure your rating works correctly, set up access rules in Firebase:
Go to “Realtime Database” -> “Rules”.
Set open access for writing and reading data:
{ "rules": { ".read": true, ".write": true } }
⚠️ Note: Make sure the database is protected and access is limited to necessary operations only.
Setting up Firebase Database Rules 🔒
Which Firebase rules are suitable for real-world use?
For a star rating, access must be restricted in such a way that:
The user could vote only with a unique IP address.
Other users could read the rating data to display the average rating and total votes.
Prevent accidental or malicious deletion of data.
Here's an example of the actual rules for how the star rating system works:
{ "rules": { "ratings": { "$postId": { "users": { "$userIP": { ".read": true, ".write": "!data.exists()", // Allow writing only if this IP address does not exist ".validate": "newData.child('rating').val() >= 1 && newData.child('rating').val() <= 5" } }, ".read": true } } } }
Explanation of the rules:
.read:
Reading data is allowed for all users
.write:
A user can write data only once (if the data record does not already exist).
This prevents the possibility of voting multiple times for the same post.
.validate:
Checks that the rating value is a number between 1 and 5 to ensure the data is valid.
Why are such strict rules important?
Security: Rules prevent manipulation of data (eg removing or adding incorrect votes).
Fairness: Limiting one entry per user ensures fairness of the rankings.
Speed: Firebase processes requests on the server side, reducing the load on the client application.
Writing Basic JavaScript for Star Rating 🚀
What JavaScript code is needed to implement star rating?
The main JavaScript code consists of the following parts:
Initializing Firebase - to connect to the database
Saving votes — recording user data in Firebase.
Updating data on the page — dynamic update of the average rating and number of votes.
Adding a hint - the message "Vote counted" appears above the pressed star after the votes have been successfully updated.
Full JavaScript code:
document.addEventListener('DOMContentLoaded', () => { const firebaseConfig = { apiKey: "YOUR_API_KEY", authDomain: "YOUR_PROJECT_ID.firebaseapp.com", projectId: "YOUR_PROJECT_ID", databaseURL: "https://YOUR_PROJECT_ID.firebaseio.com", storageBucket: "YOUR_PROJECT_ID.appspot.com", messagingSenderId: "YOUR_SENDER_ID", appId: "YOUR_APP_ID" }; // Initializing Firebase if (!firebase.apps.length) { firebase.initializeApp(firebaseConfig); } const database = firebase.database(); const postId = document.querySelector('meta[property="og:url"]')?.getAttribute('content')?.split('/').pop()?.replace('.html', '') || 'unknown_post'; const ratingElement = document.querySelector('.rating'); if (!ratingElement) return; ratingElement.dataset.postId = postId; // Getting an IP address fetch('https://api.ipify.org?format=json') .then(response => response.json()) .then(data => { const sanitizedIP = data.ip.replace(/\./g, '_'); // IP Address Conversion const userRef = database.ref(`ratings/${postId}/users/${sanitizedIP}`); // Checking if a user has voted userRef.once('value').then((snapshot) => { if (snapshot.exists()) { const savedRating = snapshot.val().rating; const starInput = ratingElement.querySelector(`input[value="${savedRating}"]`); if (starInput) { starInput.checked = true; } ratingElement.querySelectorAll('input').forEach(input => input.disabled = true); } }); const inputs = ratingElement.querySelectorAll('input'); inputs.forEach((input) => { input.addEventListener('change', () => { const rating = parseInt(input.value); userRef.set({ rating: rating, timestamp: Date.now() }).then(() => { ratingElement.querySelectorAll('input').forEach(input => input.disabled = true); }).catch((error) => { console.error('Error saving voice:', error); }); }); }); // Update average rating and number of votes const votesRef = database.ref(`ratings/${postId}/users`); votesRef.on('value', (snapshot) => { if (snapshot.exists()) { const votes = snapshot.val(); const totalVotes = Object.keys(votes).length; const averageRating = ( Object.values(votes).reduce((sum, user) => sum + user.rating, 0) / totalVotes ).toFixed(1); // Updating HTML document.getElementById('average-rating').innerText = `${averageRating}`; document.getElementById('total-votes').innerText = `${totalVotes}`; document.getElementById('average-rating-search').innerText = `${averageRating}`; document.getElementById('total-votes-search').innerText = `${totalVotes}`; // Show tooltip above last clicked star const lastClickedLabel = ratingElement.querySelector('input:checked')?.nextElementSibling; if (lastClickedLabel) { const tooltip = document.createElement('div'); tooltip.className = 'rating-tooltip'; tooltip.innerText = 'The vote has been counted'; lastClickedLabel.appendChild(tooltip); // Show a hint for 2 seconds tooltip.style.display = 'block'; setTimeout(() => { tooltip.remove(); }, 2000); } } else { document.getElementById('average-rating').innerText = `0`; document.getElementById('total-votes').innerText = `0`; document.getElementById('average-rating-search').innerText = `0`; document.getElementById('total-votes-search').innerText = `0`; } }); }) .catch(error => { console.error('Error getting IP address:', error); }); });
Explanation of key blocks:
Initializing Firebase
Connect to a database to save user votes and read rating data.
Saving Voice to Firebase
When a star is selected, the user's vote is saved in the database with their unique IP address.
Updating HTML Elements
Average rating and total votes are updated in real time.
Adding a hint
After the data has been successfully updated, the message "Vote counted" appears above the selected star.
What part of JavaScript code is adapted for Blogger?
There is a specific block in the code that extracts the post id from the Blogger URL. This allows you to link the rating to a specific post. The whole process looks like this:
const postId = document.querySelector('meta[property="og:url"]')?.getAttribute('content')?.split('/').pop()?.replace('.html', '') || 'unknown_post';
document.querySelector('meta[property="og:url"]'):
Retrieves the URL of the current page via the og:url meta tag, which is automatically generated by Blogger.
.getAttribute('content'):
Gets the full URL (eg https://yourblog.blogspot.com/2023/04/sample-post.html).
.split('/').pop():
Splits the URL at the / character and gets the last part (e.g. sample-post.html).
.replace('.html', ''):
Removes .html to leave just the post ID (eg sample-post).
|| 'unknown_post':
If the ID cannot be determined (e.g. not on the post page), a default value is set.
Why is this important for Blogger?
Blogger uses a specific URL structure for post pages.
Thanks to this block, the rating will always be linked to the unique id of a specific post, which prevents confusion when saving data in the database.
Adding HTML and CSS for Star Rating 🌐
What HTML markup should I use for star rating?
The HTML markup for the star rating should be minimalistic, readable, and easily integrated into the Blogger template. It will contain elements for displaying stars, dynamically updating the rating, and a tooltip.
HTML code:
<div class='rating' data-post-id=''> <input id='star5' name='rating' type='radio' value='5'/> <label data-tooltip='' for='star5'>★</label> <input id='star4' name='rating' type='radio' value='4'/> <label data-tooltip='' for='star4'>★</label> <input id='star3' name='rating' type='radio' value='3'/> <label data-tooltip='' for='star3'>★</label> <input id='star2' name='rating' type='radio' value='2'/> <label data-tooltip='' for='star2'>★</label> <input id='star1' name='rating' type='radio' value='1'/> <label data-tooltip='' for='star1'>★</label> </div><span id='average-rating'> Loading...</span> / <span id='total-votes'> Loading...</span>
What CSS code is needed for star rating?
CSS is responsible for the appearance of the rating. It includes styles for stars, tooltips, and the results display area.
CSS code:
.rating { direction: rtl; } .rating input { display: none; } .rating label { font-size: 2em; color: #ccc;position: relative; cursor: pointer; } .rating input:checked ~ label { color: #FF6A00; } .rating label:hover { color: #FF6A00;text-shadow: 1px 1px 2px #2E7CAD; } .rating label:hover ~ label { color: #FF6A00; } /* Tooltip styles */ .rating-tooltip { position: absolute; bottom: 100%; /* Appears above the star */ left: 50%; transform: translateX(-50%); background-color: #2E7CAD; color: #fff; padding: 5px 10px; font-size: 14px; white-space: nowrap; display: none;/* Hidden by default */ z-index: 1000; }
How does this work:
Radio buttons (input[type="radio"]):
Used to select stars.
Visually hidden, but remain functional.
Tags (label):
The appearance of the stars is specified using the symbols ★ (Unicode stars).
Associated with radio buttons for interaction.
Tooltip (rating-tooltip):
Appears dynamically above the selected star.
Set via JavaScript after a successful voice update.
Dynamic ranking update in microdata for search 🔎
What is microdata and why is it needed for star rating?
Micro-markup is a special code added to a page that helps search engines like Google understand the structure and content of your site. In the case of star ratings, micro-markup allows you to:
Display ranking in Google search results.
Draw users' attention to your content with beautiful star visualizations.
Increase your CTR (Click-Through Rate) by increasing traffic to your blog.
How to set up microdata for star rating?
To dynamically update rating data in microdata we need:
Add basic JSON-LD to Blogger template.
Update rating data (totalVotes and averageRating) in real time using JavaScript.
Step 1: Adding Basic JSON-LD
Add the following markup to your Blogger template, next to the rating HTML code:
<script type="application/ld+json" id="microdata-rating"> { "@context": "https://schema.org", "@type": "CreativeWork", "name": "Title of your post", "aggregateRating": { "@type": "AggregateRating", "ratingValue": "0", "ratingCount": "0" } } </script>
Explanation:
@context: Specifies that Schema.org markup is used.
@type: Content type. Here it is CreativeWork, but for products you can use Product.
aggregateRating: Includes rating data (ratingValue for average rating and ratingCount for number of votes).
Step 2: Dynamically updating microdata
Include rating data update in JavaScript code:
votesRef.on('value', (snapshot) => { if (snapshot.exists()) { const votes = snapshot.val(); const totalVotes = Object.keys(votes).length; const averageRating = ( Object.values(votes).reduce((sum, user) => sum + user.rating, 0) / totalVotes ).toFixed(1); // We are updating HTML document.getElementById('average-rating').innerText = `${averageRating}`; document.getElementById('total-votes').innerText = `${totalVotes}`; // Updating micro-markup JSON-LD const microdata = document.getElementById('microdata-rating'); if (microdata) { microdata.innerText = JSON.stringify({ "@context": "https://schema.org", "@type": "CreativeWork", "name": document.title, "aggregateRating": { "@type": "AggregateRating", "ratingValue": averageRating, "ratingCount": totalVotes } }); } } else { document.getElementById('average-rating').innerText = `0`; document.getElementById('total-votes').innerText = `0`; // Resetting micro-markup const microdata = document.getElementById('microdata-rating'); if (microdata) { microdata.innerText = JSON.stringify({ "@context": "https://schema.org", "@type": "CreativeWork", "name": document.title, "aggregateRating": { "@type": "AggregateRating", "ratingValue": "0", "ratingCount": "0" } }); } } });
Explanation:
Dynamic update of micro-markup:
Each time the rating changes, the ratingValue and ratingCount data is updated in JSON-LD.
Micro-markup always remains relevant for Google search.
Resetting data:
If there are no votes, the rating is reset to 0.
Dynamically updating micro-markup in HTML via itemprop 🔧
How to dynamically update microdata for search via HTML attributes?
Micro-markup can be created not only in JSON-LD format, but also directly in HTML using the itemprop, itemscope, and itemtype attributes. These attributes help search engines read rating data.
Step 1: HTML code for microdata with itemprop
Add the following block to your template, which will be updated dynamically using JavaScript:
<div itemprop='aggregateRating' itemscope='' itemtype='http://schema.org/AggregateRating' style='display:none;'><span id='average-rating-search' itemprop='ratingValue'>0</span> stars - based on <span id='total-votes-search' itemprop='reviewCount'>0</span> reviews</div>
Explanation:
itemprop="aggregateRating": Indicates that this is a block with aggregated rating data.
itemtype="http://schema.org/AggregateRating": Defines the type of data to search for.
itemprop="ratingValue" and itemprop="reviewCount": Contains data about the average rating (ratingValue) and the number of votes (reviewCount).
Step 2: Dynamically update via JavaScript
Add a block to your JavaScript code to update the values of average-rating-search and total-votes-search:
votesRef.on('value', (snapshot) => { if (snapshot.exists()) { const votes = snapshot.val(); const totalVotes = Object.keys(votes).length; const averageRating = ( Object.values(votes).reduce((sum, user) => sum + user.rating, 0) / totalVotes ).toFixed(1); // Updating HTML for the user document.getElementById('average-rating').innerText = `${averageRating}`; document.getElementById('total-votes').innerText = `${totalVotes}`; // Updating micro-markup for search document.getElementById('average-rating-search').innerText = `${averageRating}`; document.getElementById('total-votes-search').innerText = `${totalVotes}`; } else { // If there are no votes, we reset the data document.getElementById('average-rating').innerText = `0`; document.getElementById('total-votes').innerText = `0`; // Resetting micro-markup document.getElementById('average-rating-search').innerText = `0`; document.getElementById('total-votes-search').innerText = `0`; } });
How does this work:
Real time:
Every time Firebase data changes (adding a new vote), the script updates the data in the micro-markup and on the visible part of the site.
Search support:
Search engines read the new ratingValue and reviewCount values, ensuring that the data in the search results is up-to-date.
Data reset:
If there are no votes, the values are reset to 0.
Integration tips:
Hiding microdata: Use style="display:none;" to make microdata invisible to the user but visible to search engines.
Code Cleanliness: Separate HTML for users and schema markup to improve readability and maintainability.
Now your star rating is ready to work with microdata via both JSON-LD and HTML attributes.
Where to post star rating on Blogger? 📍
On which Blogger pages is it appropriate to place a star rating?
Whether or not to include a star rating depends on the type of page and the goals of your blog..
Placement recommendations:
Post Pages (useful) ⭐ Why?
Each post has unique content that visitors can appreciate.
Post rank helps users find the most popular posts and can impact your SEO (rank is displayed in search results).
Using a unique post ID allows ratings to be saved correctly in the database.
Home page (not appropriate) 🚫 Why not?
The main page displays a list of all posts, not just one specific one.
Placing a rating on the home page can be confusing for users.
Tag or category pages (not practical) 🚫 Why not?
These pages group posts by topic, but are not intended for evaluation.
Placing a rating at the category level does not make logical sense.
Static pages (possible) ✅ When is it appropriate?
If a static page represents unique content, such as an article or portfolio, it can be rated using a star rating.
Summary and implementation tips ✨
We've covered the full process of creating a star rating for the Blogger platform, from a theoretical introduction and analysis of the benefits of your own rating to the implementation of a functional widget with a connection to Firebase. You now have a fully working tool for evaluating your blog content.
Tips for successful implementation on Blogger::
Testing before launch:
Test the widget on draft blog pages to ensure that the rating is displayed and saved correctly.
Check your microdata using Google Structured Data Testing Tool.
Design update:
Customize the appearance of your star rating to match the style of your blog.
Change the size and colors of the stars using CSS.
Access restriction:
Use Firebase rules to prevent duplicate voting.
Make sure that rating and vote count data is protected from malicious users.
SEO optimization:
Place microdata on your post pages to improve search results.
Make sure that the ranking data is updated dynamically and matches the content of the page.
Feedback from users:
Add notifications for users that their vote has been successfully counted.
Regularly analyze ratings data to better understand your audience's preferences.
Conclusion:
Creating your own star rating is not just a technical process, but also a great opportunity to improve your blog, make it more interactive and user-friendly. Now you are fully prepared to implement a rating on the Blogger platform.