AdSense Says Low Value Content on Your GitHub Pages Blog: What to Fix
A github.io site can be approved for AdSense because github.io is on the Public Suffix List, but ads.txt must sit at the root of the host AdSense reviews, and a stale sitemap or a burst of short AI-assisted posts will keep triggering low value content. Fix ads.txt and indexing first, then rebuild your best posts around your own test results before reapplying.
A tech blog on GitHub Pages that keeps coming back from AdSense with "Low value content" usually has two problems stacked on top of each other: something about the hosting setup makes the site harder for Google to read and trust, and something about the content makes it look thin or mass produced. This guide separates the two so you can fix each one, then reapply once instead of five more times.
Is a github.io site even eligible for AdSense?
Yes, with conditions. AdSense's site management rules accept three kinds of sites: your own domain (like example.com), subdomains on platforms that are on the Public Suffix List, and sites run by AdSense host partners such as Blogger. github.io is on the Public Suffix List, so a user site at yourname.github.io counts as its own site, the same way a site on appspot.com does.
The catch is ads.txt. AdSense checks for the file at the root of the host it is reviewing. For a user site that means https://yourname.github.io/ads.txt, which you control by putting ads.txt in the root of the yourname.github.io repository. If your blog is a project site instead, served from yourname.github.io/blog/, the file has to live in the user site repository, not the blog repository. Plenty of people get stuck because their ads.txt sits at /blog/ads.txt, where AdSense never looks.
Check it from a terminal before you do anything else:
curl -sI https://yourname.github.io/ads.txt | head -1 curl -s https://yourname.github.io/ads.txt
The first line should say HTTP/2 200, and the body should contain one line in this form, with your own publisher ID:
google.com, pub-0000000000000000, DIRECT, f08c47fec0942fa0
If you see two different pub- IDs in your page source or in ads.txt, remove the one that is not yours. A copied theme or an old snippet left behind by a previous owner is the usual cause.
Why a custom domain still helps
Eligibility is not the same as the best setup. A domain you own costs around $10 to $15 a year and gives you three things a github.io address cannot: the site survives a move off GitHub, your ads.txt and Search Console property belong to a name you control, and the address reads as a publication rather than a repository. If you plan to keep the blog for years, move it now, before you build up links to the github.io address.
The setup takes about fifteen minutes plus DNS time:
- In the repository, open Settings, then Pages under "Code, planning, and automation", type your domain into Custom domain and click Save.
- At your DNS provider, add four A records for the apex domain pointing to
185.199.108.153,185.199.109.153,185.199.110.153and185.199.111.153. - Add a CNAME record for
wwwpointing toyourname.github.io(no repository name). - Back on the Pages settings screen, tick Enforce HTTPS. GitHub notes this can take up to 24 hours to become available.
- Add the new domain as a Domain property in Search Console and submit the sitemap there. GitHub Pages redirects the github.io address to the custom domain, so old links keep working.
Then add the new domain to AdSense as a new site and put ads.txt at its root. Do not reapply on the old github.io entry once the domain is live; review the address you actually want ads on.
The sitemap that stopped updating
A common symptom on Jekyll blogs is a Search Console sitemap report whose "Last read" date is months or years old, even though new posts go up every week. That alone does not cause a rejection, but it tells you Google is discovering your new posts slowly, and a reviewer may be looking at a site where only your oldest pages are indexed.
Work through it in this order:
- Open the sitemap URL in a browser, for example
https://yourname.github.io/sitemap.xml. Confirm it loads, lists your newest post, and that every URL uses the same host and protocol you serve (https, and either github.io or your custom domain, never a mix). - If you use the
jekyll-sitemapplugin, check that it is listed underplugins:in_config.ymland thaturl:in the same file matches your live address. A wrongurlvalue produces a sitemap full of addresses Google will not index. - In Search Console, go to Indexing, then Sitemaps, remove the stale entry and submit the sitemap again. A fresh submission forces a new read.
- Run two or three of your newest posts through URL Inspection and click Request indexing. If they come back as "Discovered, currently not indexed", Google knows about them but has not judged them worth crawling yet, which points back at content.
Also check robots.txt. Some themes ship one that blocks /assets/ or the whole site during development, and nobody remembers to change it.
What "low value content" means for a tech blog
Google does not tell you which pages failed. In practice, for machine learning and data science blogs, the reviewer is comparing your pages to the thousands of tutorials that already explain the same library calls. Three patterns trigger the rejection most often:
- Restated documentation. A post that walks through
train_test_splitor a basic PyTorch training loop with the same toy dataset as the official tutorial adds nothing a reader cannot get from the source. - Volume over depth. Two or three posts a day, written with AI help, look like a content farm even when each one is based on real work. Posting frequency is not a ranking or approval signal. A sudden burst of short posts tends to hurt more than it helps.
- Thin pages. Notes, half finished drafts, tag pages and category archives with a few lines each all count toward the site the reviewer sees.
The fix is to make your own work visible. If you ran an experiment on your machine, show it: the hardware, the dataset size, the exact versions, the numbers you got, a chart of the results, and what surprised you. A post that says "on an RTX 3060 with 12 GB, batch size 64 ran out of memory at epoch 3, so here is what I changed" carries something no other page has. That is the kind of original value AdSense reviewers look for, and it is also what earns links from other developers.
A two week plan before you reapply
- Days 1 and 2: fix ads.txt, remove any second publisher ID, and decide on github.io or a custom domain. If you are moving, do it now.
- Days 3 and 4: list every page on the site. Merge or delete posts under about 300 words that only restate documentation. Set tag and category archives to
noindexif they are thin. - Days 5 to 10: take your ten best posts and add the original material: results tables, screenshots of your own output, error messages you hit and how you solved them, and a short "what I would do differently" section. Ten strong posts beat fifty weak ones.
- Days 11 and 12: make sure the About page names you and explains your background, the Contact page works, and the Privacy Policy mentions cookies and Google advertising. Check the site on a phone; GitHub Pages themes from a few years ago often break on narrow screens.
- Days 13 and 14: resubmit the sitemap, confirm the improved posts are indexed in URL Inspection, then reapply. Slow down to one or two solid posts a week while you wait.
If you want a quick read on the structural side, the free site checker runs 30 checks on any URL, including ads.txt, robots.txt, sitemap and the basic pages AdSense expects, in about ten seconds.
Where this question came from
- r/Blogging: Need Help Getting AdSense Approval for My Tech Blog
- Google AdSense Help: Site management is changing in AdSense
- GitHub Docs: Managing a custom domain for your GitHub Pages site
Questions about AdSense on GitHub Pages
Can I get AdSense on a github.io address?
Yes. AdSense accepts subdomains on platforms listed in the Public Suffix List, and github.io is on it. Your ads.txt must be reachable at the root of your user site, for example yourname.github.io/ads.txt.
Where does ads.txt go for a GitHub Pages project site?
In the root of the yourname.github.io user site repository, not the project repository. AdSense only looks at the root of the host, so a file at /blog/ads.txt is never found.
Does posting several times a day help AdSense approval?
No. Posting frequency is not an approval signal, and a burst of short posts can make a site look mass produced. Fewer, deeper posts with your own results help more.
Why is my Search Console sitemap last read date so old?
Usually the sitemap URL changed, the url value in _config.yml is wrong, or the entry was never resubmitted. Check the sitemap loads with your live addresses, remove the old entry in Indexing, Sitemaps, and submit it again.