A client sent me a link last month with one line of brief: "make ours look like this." No theme name, no developer contact, no budget for a rebuild. Before I could say whether that was a fortnight of work or an afternoon of CSS, I needed to know what the site was actually running - and the fastest honest answer comes from the page itself, not from asking.
WordPress is unusually generous about this. It publishes its own structure in every page it serves, which means a site tells you what theme is rendering it whether or not anyone meant to. This guide explains where that information lives, how to read it by hand, and why the answer is sometimes missing without the site being any less WordPress. The WordPress Theme Detector does the same reading in one request.
TL;DR: Open the page source and look for a stylesheet loaded from
/wp-content/themes/<slug>/. That slug is the theme folder. Fetch/wp-content/themes/<slug>/style.cssand the header block at the top names the theme, its version, its author, and - if it is a child theme - the parent it extends in aTemplate:line. If nothing loads from/wp-content/, the site can still be WordPress: a managed host or an optimisation plugin may have rewritten the paths.
Where does a WordPress page name its own theme?
Every theme has to load its stylesheet from its own folder, and WordPress serves theme files from a fixed location: /wp-content/themes/<slug>/. So the first thing to do with any page is view source and search for wp-content/themes. What comes back looks like this:
<link rel="stylesheet" id="astra-theme-css"
href="https://example.com/wp-content/themes/astra/assets/css/minified/main.min.css?ver=4.6.2" />
The folder name between themes/ and the next slash is the answer: astra. That is a fact about the response, not a guess from how the page looks.
Three other signals sit beside it and are worth knowing, because they are what tells you the site is WordPress at all when the theme is hidden:
| Signal | Where it appears | What it proves |
|---|---|---|
/wp-content/themes/<slug>/ |
stylesheet and script URLs | the active theme's folder |
/wp-includes/ |
core script URLs like wp-emoji-release.min.js |
WordPress core is serving the page |
<link rel="https://api.w.org/"> |
<head>, and a Link: response header |
the REST API is enabled |
<meta name="generator" content="WordPress 6.7"> |
<head> |
the core version, when it has not been stripped |
The generator tag is the one most often removed. Plenty of security plugins strip it, and a line in a theme's functions.php does the same, because it advertises an exact version to anyone scanning for known issues. Its absence says nothing about whether the site is WordPress.
How do you get the theme's real name and version?
A folder slug is not a name. astra is recognisable, twentytwentyfour is obvious, but plenty of slugs are abbreviations nobody outside the agency would know. The name lives one request further on.
Every theme ships a style.css in its root, and WordPress requires that file to start with a comment block declaring itself. Fetch https://example.com/wp-content/themes/astra/style.css and the top of the file reads:
/*
Theme Name: Astra
Theme URI: https://wpastra.com/
Author: Brainstorm Force
Version: 4.6.2
Template: astra
Text Domain: astra
*/
Those header fields are not a convention someone chose to follow. The Theme Handbook makes Theme Name mandatory for any theme WordPress will accept, which is why this works on bespoke themes that were never published anywhere.
One caveat on the version, and it matters more than people expect. Version: is what the theme author wrote for that release. It is accurate on an untouched theme and unreliable the moment someone edits the files without bumping the number, which happens constantly on sites that have been "just quickly fixed" a few times. Read it as the theme's own claim about itself.
What does it mean when two themes show up?
A page that loads stylesheets from two theme folders is almost always running a child theme.
A child theme is a small folder that overrides part of a parent rather than copying it. The child's style.css names its parent in a Template: line, and WordPress loads both folders. That relationship is the whole point: the parent can be updated without destroying the customisations, which is the recommended way to modify any theme you did not write.
So when you see both astra and astra-child, the active theme is astra-child and the parent is astra. The Template: field is what settles it, rather than guessing from the folder names - plenty of child themes are not named after their parent at all.
This is also where automated answers go wrong in a specific, repeatable way. A catalogue lookup that matches a slug to a published theme will happily recognise the parent, because the parent is the published one, and report that as the answer. The page is the better authority here: the stylesheet it loads is what is rendering it, full stop.
Why does a site show no theme at all?
This is the case worth understanding, because it is where a confident tool lies to you.
Several ordinary setups erase the theme folder from the page:
- A caching or optimisation plugin that concatenates every stylesheet into one combined file under
/wp-content/cache/. The merged file contains the theme's CSS; the theme's folder name is gone from the markup. - A host or CDN that serves assets from a rewritten path, so
/wp-content/themes/astra/...arrives as/assets/a1b2c3.css. - A headless setup, where WordPress is the admin and the API but something else renders the front end. There is no theme in the usual sense.
- A site that is simply not WordPress.
Those four look identical from outside if all you check is "did I find a theme folder". They are not the same answer, and reporting the first three as "not WordPress" is wrong in the confident direction. Check the other signals - /wp-includes/, the REST API link, the wp-json route - before concluding anything. A site can serve none of its theme paths and still answer https://example.com/wp-json/ with a JSON index, which settles it.
Scanning an interior page rather than the homepage also helps more than people expect. Homepages are the most heavily cached and most aggressively optimised page on most sites; a blog post or a contact page frequently loads the theme's own files untouched.
Is it legal, and does the site owner find out?
Reading a public page is a normal request. Your browser makes the same one every time you visit, and the site's access log records it the same way it records every other visitor. Nothing about checking a theme touches the admin area, submits a form, or attempts a login.
What you do with the answer is the part with rules. A theme's name and version are facts; the theme's code is licensed, and most WordPress themes are GPL, which grants you a great deal but is not the same as "anything goes" with someone's brand, their images, or their content. Identifying a theme so you can buy the same one is the normal use. Copying a site is not a theme question.
How do you check quickly, without reading source?
By hand the sequence is: view source, search wp-content/themes, take the slug, fetch that folder's style.css, read the header. From a terminal it is two commands:
curl -s https://example.com | grep -o 'wp-content/themes/[^/]*' | head -1
curl -s https://example.com/wp-content/themes/astra/style.css | head -20
The WordPress Theme Detector runs exactly that, follows the child-to-parent link, and lists the signals it used so you can check the reasoning rather than trusting a verdict. It also separates the three outcomes that matter: theme found, WordPress but the theme could not be read, and no WordPress signals at all.
Plugins are a separate question with separate evidence and a much bigger caveat, which is why they are a separate tool - the WordPress Plugin Detector reads the same page for what is loading on it. And if you are on the other side of this, publishing a theme or plugin of your own, the readme generator writes the readme.txt the WordPress.org directory parses.



