Publish in rankveo, render the blog on your own Rails site. The best SEO, GEO and AEO content tooling, on your domain — server rendered HTML, not an embed.
# Gemfile
gem "rankveo-rails"# config/initializers/rankveo.rb
Rankveo.configure do |config|
config.api_key = ENV.fetch("RANKVEO_BLOG_API_KEY")
end# config/routes.rb
mount Rankveo::Rails::Engine, at: "/blog"That is the whole setup.
| Route | |
|---|---|
/blog |
Paginated listing |
/blog/page/2 |
Real paths, not ?page= — every page is crawlable |
/blog/:slug |
Article, with Open Graph and BlogPosting JSON-LD |
/blog/tag/:slug, /blog/category/:slug |
Filtered listings, paginated |
/blog/feed |
RSS |
/blog/sitemap.xml |
Sitemap with image entries — Google will not index an image it has to find by crawling |
config.revalidate_secret = ENV.fetch("RANKVEO_REVALIDATE_SECRET")rankveo then calls POST /blog/rankveo/revalidate whenever an article is
published, edited while live, unpublished or deleted, and the blog cache is
cleared. Without a secret the route is not drawn at all — an unauthenticated
cache-busting endpoint is a free way to make every request hit the API.
This is where Rails beats a static site generator: there is a real cache to invalidate, so nothing has to rebuild or redeploy.
articles = Rankveo.blog.articles(page: 0)
article = Rankveo.blog.find_article("how-to-rank-in-ai-answers")
site = Rankveo.blog.siteResponses go through Rails.cache. Rankveo.blog.fresh is the uncached client;
Rankveo.blog.flush clears everything.
Articles respond to to_param, so blog_article_path(article) works.
The engine is isolated, and your application's view paths win over an engine's. Create any of these to override:
app/views/layouts/rankveo/blog.html.erb # put the blog inside your site chrome
app/views/rankveo/blog/index.html.erb
app/views/rankveo/blog/show.html.erb
The layout is deliberately plain. The class names are the same semantic ones every rankveo starter uses.
| Option | Default |
|---|---|
api_key |
ENV["RANKVEO_BLOG_API_KEY"] |
base_url |
https://api.rankveo.com/api |
timeout |
10.0 |
cache_expires_in |
1.hour — nil disables caching |
per_page |
9 |
site_url |
derived from the request |
site_name, site_description |
"Blog", "" |
revalidate_secret |
ENV["RANKVEO_REVALIDATE_SECRET"] |
mount_path |
"/blog" |
- The key is server-side. It is never needed in a browser.
- Body images are already in
article.html. Looping overarticle.imagesas well prints them twice — usearticle.gallery_imagesfor the rest. - An article from a listing has no body.
article.body?says so; it is the usual cause of a blank article page. - The cache stores hashes, not Structs.
Rails.cachemarshals values, and a marshalled Struct breaks in production the first time a member is added or renamed. Objects are rebuilt on read instead.
MIT.