Astrology Widget for WordPress: Shortcode and Block Tutorial
Add a daily horoscope, natal chart, kundli, and Life Path widget to WordPress with one shortcode pattern, transient caching, and a custom REST proxy.
TL;DR
- WordPress runs 42.2% of the public web (W3Techs, May 2026), so an astrology widget for WordPress is the highest-leverage place to ship a horoscope, natal chart, or kundli feature.
- The single canonical pattern: store the API key in
wp-config.php, register a shortcode withadd_shortcode, call RoxyAPI throughwp_remote_getorwp_remote_post, cache responses withset_transient. - One key, ten domains. The same five lines that ship daily horoscope ship Vedic kundli, dream symbol lookup, and Life Path numerology.
- Build this with the Astrology API in under 20 minutes.
About the author: Brett Calloway is a Developer Advocate and AI Integration Specialist with 12 years of experience in API development. He writes on building context-rich AI agents and rapid prototyping with astrology, tarot, and numerology data, drawing on a developer relations background.
WordPress dominates the public web. The May 2026 W3Techs reading puts it at 42.2% of all websites, with WooCommerce alone covering roughly 20% of every WordPress install. That makes WordPress the single biggest distribution surface for any horoscope plugin, daily-card widget, kundli generator, or numerology calculator. The bar to ship one is not framework knowledge. The bar is one shortcode, one API call, and one transient cache. This guide walks the canonical pattern end to end with the daily horoscope, then scales it to natal charts, Vedic kundli, dreams, and Life Path numerology, all on the same key.
How do I add an astrology widget to WordPress in under 20 minutes?
Register a shortcode that calls the Astrology API and returns HTML. That is the entire pattern. WordPress shortcodes are PHP callbacks bound to a tag like [roxy_horoscope sign="leo"]; once registered, the tag works in every post, page, widget area, and Gutenberg Shortcode block. The four moving parts: an API key in wp-config.php, a callback that runs wp_remote_get, a set_transient cache so identical requests do not double-bill against rate limits, and HTML output sanitized with esc_html. The full daily horoscope shortcode is 30 lines, ships as a single Code Snippets entry, and survives theme switches.
Total time for a developer who has SFTP access or the Code Snippets plugin: under 20 minutes from blank site to rendered horoscope card. If you want the canonical multi-domain reference with every snippet inline, the WordPress integration guide is the long-form companion to this post.
Where should I store the RoxyAPI key on WordPress?
In wp-config.php as a PHP constant. That places the key outside the database, outside any theme file, and outside the request body. WordPress reads wp-config.php on every request, so a define call for ROXY_API_KEY becomes available globally with zero startup cost. The Code Snippets plugin path is the second-best option for sites without SFTP access; it stores the snippet in the wp_snippets table, so any database export contains the key, but the boundary between the key and frontend code is preserved.
Never put the API key in a theme file that loads on the frontend, a wp_options row, a custom field, post meta, a JavaScript bundle, or a REST response. Any of those either ships the key to the browser or surfaces it in a routine database dump.
Ready to build this? Astrology API gives you all 10 spiritual domains behind one key with 130+ endpoints, MCP-first agent support, and accuracy verified against NASA JPL Horizons. See the full API reference.
The four practical places to put the PHP code, ranked by survivability:
| Location | Persists across | Best for | Caveats |
|---|---|---|---|
| Code Snippets plugin | Theme switches, plugin updates | Non-developers, hosted WordPress, fastest path | Snippet stored in the database, included in every export |
Child theme functions.php | Parent theme updates | Sites with one fixed theme | Lost when the active theme changes |
mu-plugins/ directory | Theme switches, plugin pages, core updates | Sites where the widget is permanent infrastructure | Requires SFTP or file-manager access |
Custom plugin (in plugins/) | Theme switches, version control | Sites where you want to ship the widget separately or to clients | Requires plugin file scaffolding |
Avoid editing the parent theme functions.php directly. Theme updates wipe it.
The daily horoscope shortcode end to end
The daily horoscope is the single highest-volume astrology query on the web, so it is the right place to start. The endpoint is GET /api/v2/astrology/horoscope/{sign}/daily and the response carries sign, overview, love, career, health, finance, advice, luckyNumber, luckyColor, compatibleSigns, activeTransits, moonSign, moonPhase, and energyRating. Field names are camelCase. Match them byte-for-byte; a lucky_number reference returns blank because the field is luckyNumber.
Wrap every external call in get_transient and set_transient. Daily content does not change within the day, so an hour-long transient saves at least 24 calls per sign per day, keeps your rate-limit headroom for the chart endpoints that actually cost compute, and makes the widget render in microseconds on every cache hit.
<?php
add_shortcode( 'roxy_horoscope', 'roxy_horoscope_shortcode' );
function roxy_horoscope_shortcode( $atts ) {
$atts = shortcode_atts( array( 'sign' => 'aries' ), $atts, 'roxy_horoscope' );
$sign = sanitize_key( $atts['sign'] );
$valid = array( 'aries','taurus','gemini','cancer','leo','virgo','libra','scorpio','sagittarius','capricorn','aquarius','pisces' );
if ( ! in_array( $sign, $valid, true ) || ! defined( 'ROXY_API_KEY' ) ) {
return '<p>Horoscope unavailable.</p>';
}
$cache_key = 'roxy_horoscope_' . $sign;
$cached = get_transient( $cache_key );
if ( false !== $cached ) {
return $cached;
}
$response = wp_remote_get(
'https://roxyapi.com/api/v2/astrology/horoscope/' . $sign . '/daily',
array( 'headers' => array( 'X-API-Key' => ROXY_API_KEY ), 'timeout' => 10 )
);
if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
return '<p>Could not load today horoscope.</p>';
}
$data = json_decode( wp_remote_retrieve_body( $response ), true );
$html = '<div class="roxy-horoscope">';
$html .= '<h3>' . esc_html( $data['sign'] ) . ' daily horoscope</h3>';
$html .= '<p>' . esc_html( $data['overview'] ) . '</p>';
$html .= '<p><strong>Love:</strong> ' . esc_html( $data['love'] ) . '</p>';
$html .= '<p><strong>Career:</strong> ' . esc_html( $data['career'] ) . '</p>';
$html .= '<p>Lucky number ' . intval( $data['luckyNumber'] ) . ', lucky color ' . esc_html( $data['luckyColor'] ) . '.</p>';
$html .= '</div>';
set_transient( $cache_key, $html, HOUR_IN_SECONDS );
return $html;
}
curl -s "https://roxyapi.com/api/v2/astrology/horoscope/leo/daily" \
-H "X-API-Key: $ROXY_API_KEY"
Sample response shape (trimmed):
{
"sign": "Leo",
"date": "2026-05-04",
"overview": "...",
"love": "...",
"career": "...",
"luckyNumber": 7,
"luckyColor": "Gold",
"compatibleSigns": ["Aries", "Sagittarius", "Gemini"],
"moonPhase": "Waxing Gibbous Moon",
"energyRating": 7
}
Drop [roxy_horoscope sign="leo"] into a Shortcode block in any post or page. The card renders the sign heading, daily overview, love line, career line, and lucky number plus color, all sanitized.
Custom REST proxy for client-side widgets
If you want a JavaScript widget that fetches a fresh sign on click, register a custom REST route that proxies the call. The browser only sees /wp-json/roxy/v1/horoscope/leo; the API key never leaves the server.
add_action( 'rest_api_init', function () {
register_rest_route( 'roxy/v1', '/horoscope/(?P<sign>[a-z]+)', array(
'methods' => 'GET',
'callback' => 'roxy_rest_horoscope',
'permission_callback' => '__return_true',
) );
} );
function roxy_rest_horoscope( $request ) {
$sign = strtolower( $request['sign'] );
if ( ! defined( 'ROXY_API_KEY' ) ) {
return new WP_Error( 'no_key', 'Key missing', array( 'status' => 500 ) );
}
$cache_key = 'roxy_rest_horoscope_' . $sign;
$cached = get_transient( $cache_key );
if ( false !== $cached ) {
return rest_ensure_response( $cached );
}
$response = wp_remote_get(
'https://roxyapi.com/api/v2/astrology/horoscope/' . $sign . '/daily',
array( 'headers' => array( 'X-API-Key' => ROXY_API_KEY ), 'timeout' => 10 )
);
$data = json_decode( wp_remote_retrieve_body( $response ), true );
set_transient( $cache_key, $data, HOUR_IN_SECONDS );
return rest_ensure_response( $data );
}
After registering, visit Settings, Permalinks in wp-admin and click Save. WordPress regenerates the rewrite rules; without that, the new route returns a 404.
How to scale from horoscope to natal charts, kundli, and Life Path
The shortcode pattern generalizes to every endpoint on the platform. Swap the URL, swap the request method, swap the field names, keep the cache. The four most common widgets a WordPress site ships beyond daily horoscope:
- Natal chart.
POST /api/v2/astrology/natal-chartwith body{ date, time, latitude, longitude, timezone, houseSystem }. Thetimefield isHH:MM:SS, notHH:MM. The response carriesplanets[],houses[],aspects[],ascendant,midheaven,summary. Usewp_remote_postandwp_json_encodefor the body, plus theContent-Type: application/jsonheader. Cache forDAY_IN_SECONDSbecause birth charts are immutable. - Vedic kundli.
POST /api/v2/vedic-astrology/birth-chartwith the samedate, time, latitude, longitude, timezonebody. Response is keyed by sign (aries,taurus, ...,pisces); each sign carriessigns[]with planet placements includingnakshatra.nameandnakshatra.pada. Thetimezonefield accepts decimal hours (5.5) or IANA strings (Asia/Kolkata). - Life Path number.
POST /api/v2/numerology/life-pathwith body{ year, month, day }as integers (not abirthDatestring). Response carriesnumber,calculation,type,hasKarmicDebt, andmeaningwithtitle,keywords,description,strengths,challenges,career,relationships,spirituality. Cache forever (WEEK_IN_SECONDS). - Dream symbol lookup.
GET /api/v2/dreams/symbols?q=snakefor search or/api/v2/dreams/symbols/{id}for a specific symbol by kebab-case identifier. Response shape includesid,name,letter,meaning. Static dictionary content, so cache forWEEK_IN_SECONDS.
For coordinate-dependent endpoints (natal chart, kundli), call GET /api/v2/location/search?q={city} first to resolve the user input into latitude, longitude, and an IANA timezone, then feed those into the chart request. Prefer IANA strings over decimal offsets; decimals do not handle daylight saving and produce ascendants that drift by up to four arcminutes during DST windows. The companion add daily horoscopes in 10 lines post covers the minimal version of this pattern in any framework.
Common gotchas (cURL SSL, permalink refresh, object cache, IANA timezones)
Six failure modes account for almost every broken first install. The first three are platform-level; the last three are content-level.
| Gotcha | Symptom | Fix |
|---|---|---|
| Stale CA bundle | wp_remote_get returns cURL error 60: SSL certificate problem | Ask the host to update the CA bundle. Do not disable SSL verification; that breaks the security boundary |
| New REST route returns 404 | Custom register_rest_route URL gives 404 from the browser | Visit Settings, Permalinks, click Save once. WordPress regenerates rewrite rules |
| Object cache plugin ate the transient | Transient disappears after every cache flush | Switch to update_option for durability, or accept the per-flush re-fetch and tune HOUR_IN_SECONDS accordingly |
| Decimal timezone offset | Natal chart ascendant drifts by minutes around DST boundaries | Pass IANA strings like Europe/London instead of 0 or 1 |
| Wrong field casing | null rendered for lucky number on the horoscope card | Use luckyNumber not lucky_number. All response fields are camelCase, verified per route |
time set to HH:MM | Natal chart returns 400 validation error | Use HH:MM:SS format. The Zod schema rejects two-segment time |
Two more not in the table but worth flagging. WordPress.com Free does not allow plugins or custom code; you need the Business plan or higher for wp_remote_get to even exist in scope. And every accuracy or methodology claim on a horoscope card or kundli page should link to the methodology page rather than asserting figures inline; the methodology surface keeps the citation up to date as the test corpus grows.
FAQ
How do I add astrology to WordPress without writing PHP?
Install the free Code Snippets plugin from the WordPress.org plugin directory and paste the shortcode PHP into a new snippet. The plugin gives you a UI to manage PHP without touching theme files, and the snippet survives theme switches. The first snippet defines ROXY_API_KEY, the second registers [roxy_horoscope], and you drop the shortcode into any post or page using the Shortcode block.
Is RoxyAPI compatible with WordPress.com?
Yes on the Business plan and higher. WordPress.com Free and Personal plans block plugins and custom PHP, so neither path works. On the Business, Commerce, or Enterprise plan you can install the Code Snippets plugin and use the same shortcode pattern as a self-hosted install. Self-hosted WordPress (the wordpress.org variant) supports it on every host.
Do I need a dedicated plugin for this?
No. A single shortcode registered through Code Snippets, a child theme functions.php, or a one-file mu-plugin is enough to ship a horoscope card, natal chart, or numerology calculator. A dedicated plugin is the right move only when you plan to ship the widget to multiple client sites and want versioned releases.
Can I cache RoxyAPI responses on WordPress?
Yes, and you should. WordPress ships set_transient and get_transient for short-lived caching with no extra setup. Use HOUR_IN_SECONDS for daily horoscope, DAY_IN_SECONDS for natal charts, WEEK_IN_SECONDS for static dictionary content like dream symbols and angel numbers. If your host runs a Redis or Memcached object cache plugin, transients persist there automatically.
Does this work with WooCommerce?
Yes. The pattern is identical: register the shortcode, hook a callback to woocommerce_thankyou or woocommerce_order_status_completed, call the RoxyAPI endpoint, store the result on the order as order meta, and email it via wc_get_template. A common build is a Life Path numerology report that runs on checkout completion and ships in the order confirmation email.
Where does the API key live in production?
In wp-config.php as a define call for the ROXY_API_KEY constant, above the line that reads That is all, stop editing. The constant is available in every PHP file, never reaches the database, and never ships to the browser. For sites without SFTP access, the Code Snippets path stores the constant in the wp_snippets table, which is the next-best boundary.
Conclusion
WordPress is where the largest astrology, horoscope, and numerology audiences live, and the shortcode pattern in this post is the same five lines whether the widget shipping is a daily horoscope card, a Vedic kundli generator, or a Life Path calculator. The canonical multi-domain reference at the WordPress integration guide covers every snippet inline, and the Astrology API product page lists every endpoint that drops into the same callback. One key, ten domains, every shortcode the same pattern.