seo_geo 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/AGENTS.md +244 -0
- data/CHANGELOG.md +40 -0
- data/LICENSE.txt +21 -0
- data/README.md +428 -0
- data/app/controllers/seo_geo/index_now_controller.rb +13 -0
- data/app/controllers/seo_geo/llms_controller.rb +29 -0
- data/app/controllers/seo_geo/og_images_controller.rb +67 -0
- data/app/controllers/seo_geo/robots_controller.rb +14 -0
- data/app/controllers/seo_geo/sitemaps_controller.rb +16 -0
- data/app/jobs/seo_geo/index_now_job.rb +21 -0
- data/app/views/seo_geo/fallback/_body.html.erb +21 -0
- data/app/views/seo_geo/fallback/_faq.html.erb +12 -0
- data/config/routes.rb +17 -0
- data/lib/generators/seo_geo/install/install_generator.rb +138 -0
- data/lib/generators/seo_geo/install/templates/home.yml.tt +14 -0
- data/lib/generators/seo_geo/install/templates/initializer.rb.tt +52 -0
- data/lib/seo_geo/audit/checks.rb +107 -0
- data/lib/seo_geo/audit/html_document.rb +132 -0
- data/lib/seo_geo/audit/report.rb +85 -0
- data/lib/seo_geo/audit/runner.rb +327 -0
- data/lib/seo_geo/audit/static_scan.rb +60 -0
- data/lib/seo_geo/audit.rb +14 -0
- data/lib/seo_geo/bot_verifier.rb +278 -0
- data/lib/seo_geo/configuration.rb +832 -0
- data/lib/seo_geo/controller.rb +72 -0
- data/lib/seo_geo/crawler_fallback.rb +45 -0
- data/lib/seo_geo/crawlers.rb +79 -0
- data/lib/seo_geo/engine.rb +123 -0
- data/lib/seo_geo/index_now.rb +187 -0
- data/lib/seo_geo/json_ld.rb +259 -0
- data/lib/seo_geo/llms_txt.rb +183 -0
- data/lib/seo_geo/markdown/document.rb +163 -0
- data/lib/seo_geo/markdown/negotiation.rb +49 -0
- data/lib/seo_geo/markdown/path_suffix.rb +72 -0
- data/lib/seo_geo/markdownable.rb +141 -0
- data/lib/seo_geo/meta.rb +382 -0
- data/lib/seo_geo/model.rb +95 -0
- data/lib/seo_geo/og_image/card.html.erb +22 -0
- data/lib/seo_geo/og_image/ferrum_backend.rb +72 -0
- data/lib/seo_geo/og_image/renderer.rb +163 -0
- data/lib/seo_geo/page.rb +201 -0
- data/lib/seo_geo/path_match.rb +36 -0
- data/lib/seo_geo/publication.rb +68 -0
- data/lib/seo_geo/robots/evaluator.rb +85 -0
- data/lib/seo_geo/robots.rb +105 -0
- data/lib/seo_geo/robots_directives.rb +170 -0
- data/lib/seo_geo/robots_path.rb +125 -0
- data/lib/seo_geo/rspec.rb +197 -0
- data/lib/seo_geo/safe_regexp.rb +50 -0
- data/lib/seo_geo/sitemap/registry.rb +239 -0
- data/lib/seo_geo/sitemap/xml.rb +138 -0
- data/lib/seo_geo/testing/environment.rb +31 -0
- data/lib/seo_geo/testing.rb +111 -0
- data/lib/seo_geo/undeclared_host.rb +40 -0
- data/lib/seo_geo/version.rb +5 -0
- data/lib/seo_geo.rb +80 -0
- data/lib/tasks/seo_geo.rake +23 -0
- data/llms.txt +27 -0
- metadata +224 -0
data/llms.txt
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# seo_geo (Ruby / Rails)
|
|
2
|
+
|
|
3
|
+
> Rails engine for SEO and GEO (Generative Engine Optimization: visibility in AI search and assistants), not a geolocation gem. One initializer and one layout line give meta tags with canonical folding, JSON-LD from one page-copy source, crawler fallback bodies for Inertia/SPA pages, purpose-based AI crawler policy (training / search / user), per-host robots.txt, sitemap.xml, llms.txt, Markdown negotiation, IndexNow, OG images and an audit task.
|
|
4
|
+
|
|
5
|
+
- Install: `gem "seo_geo"` in the Gemfile, then `bin/rails g seo_geo:install https://www.example.com`. Version 0.1.0 is not yet on RubyGems; until it is, use `gem "seo_geo", github: "seunghan91/seo_geo"`.
|
|
6
|
+
- Requirements: Ruby >= 3.2, Rails 7.2 / 8.0 / 8.1 (CI covers every cell). Runtime dependencies: railties, actionpack, meta-tags ~> 2.24, reverse_markdown ~> 3.0. Optional: ferrum (OG cards), ActiveJob (IndexNow job).
|
|
7
|
+
- Public API: `SeoGeo.configure`, `SeoGeo.config`, `SeoGeo.sitemap.draw { add ... }`, `SeoGeo.page(:key)`, `SeoGeo.pages.register`; view helpers `seo_geo_head`, `seo_geo_html_lang`, `seo_geo_fallback_body(:key)`, `seo_geo_faq(:key)`; controller `seo(title:, description:, image:, noindex:, index:, canonical:, type:, json_ld:)`, `seo_geo_page(:key)`; `include SeoGeo::Markdownable` + `seo_geo_markdown only:, page:`; `SeoGeo::JsonLd`; `SeoGeo::IndexNow.submit(urls)`, model macro `seo_geo_indexnow on: :publish, url:`; `rake seo_geo:audit`; `rails g seo_geo:install`; `require "seo_geo/testing"` (Minitest) and `require "seo_geo/rspec"`; `SeoGeo::BotVerifier::Middleware`; JS `window.SeoGeo.mounted()`.
|
|
8
|
+
- Routes served when mounted at "/": `GET /robots.txt`, `/sitemap.xml`, `/llms.txt`, `/llms-full.txt`, `/<indexnow-key>.txt`, `/og/:key.png`, and `.md` for every Markdownable action.
|
|
9
|
+
- Invariants: undeclared hosts fail closed; one copy source per page; the User-Agent is never used for access decisions; no invented lastmod.
|
|
10
|
+
- License: MIT.
|
|
11
|
+
|
|
12
|
+
## Docs
|
|
13
|
+
|
|
14
|
+
- [README](https://github.com/seunghan91/seo_geo/blob/main/README.md): what it does, install, quick start, Inertia, configuration, limits
|
|
15
|
+
- [AGENTS.md](https://github.com/seunghan91/seo_geo/blob/main/AGENTS.md): when to use it, integration recipe, invariants and check commands for coding agents
|
|
16
|
+
- [Troubleshooting](https://github.com/seunghan91/seo_geo/blob/main/README.md#troubleshooting): exact error and audit messages, causes and fixes
|
|
17
|
+
- [Design and configuration contract](https://github.com/seunghan91/seo_geo/blob/main/docs/DESIGN.md): every configuration key, default and public API
|
|
18
|
+
- [Runnable examples](https://github.com/seunghan91/seo_geo/tree/main/docs/examples): the README and AGENTS code as app files, executed by the test suite
|
|
19
|
+
- [CHANGELOG](https://github.com/seunghan91/seo_geo/blob/main/CHANGELOG.md)
|
|
20
|
+
|
|
21
|
+
## Optional
|
|
22
|
+
|
|
23
|
+
- [llms.txt specification](https://llmstxt.org/): the format this gem generates
|
|
24
|
+
- [Which AI actually reads your site (Evil Martians, 2026)](https://evilmartians.com/chronicles/which-ai-actually-reads-your-site-two-months-of-llm-traffic-measured): agent traffic measurements behind the "HTML first, Markdown second, llms.txt cheap" design
|
|
25
|
+
- [RFC 9309](https://www.rfc-editor.org/rfc/rfc9309): Robots Exclusion Protocol, which the robots.txt output follows
|
|
26
|
+
- [IndexNow](https://www.indexnow.org/documentation): the protocol behind `SeoGeo::IndexNow`
|
|
27
|
+
- [webmcp](https://github.com/seunghan91/webmcp): related gem that lets in-browser agents call your app's endpoints as tools
|
metadata
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: seo_geo
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- seunghan Kim
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 2026-10-14 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: railties
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '7.2'
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '9'
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
requirements:
|
|
26
|
+
- - ">="
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
version: '7.2'
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '9'
|
|
32
|
+
- !ruby/object:Gem::Dependency
|
|
33
|
+
name: actionpack
|
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
|
35
|
+
requirements:
|
|
36
|
+
- - ">="
|
|
37
|
+
- !ruby/object:Gem::Version
|
|
38
|
+
version: '7.2'
|
|
39
|
+
- - "<"
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
version: '9'
|
|
42
|
+
type: :runtime
|
|
43
|
+
prerelease: false
|
|
44
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
45
|
+
requirements:
|
|
46
|
+
- - ">="
|
|
47
|
+
- !ruby/object:Gem::Version
|
|
48
|
+
version: '7.2'
|
|
49
|
+
- - "<"
|
|
50
|
+
- !ruby/object:Gem::Version
|
|
51
|
+
version: '9'
|
|
52
|
+
- !ruby/object:Gem::Dependency
|
|
53
|
+
name: meta-tags
|
|
54
|
+
requirement: !ruby/object:Gem::Requirement
|
|
55
|
+
requirements:
|
|
56
|
+
- - "~>"
|
|
57
|
+
- !ruby/object:Gem::Version
|
|
58
|
+
version: '2.24'
|
|
59
|
+
type: :runtime
|
|
60
|
+
prerelease: false
|
|
61
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
62
|
+
requirements:
|
|
63
|
+
- - "~>"
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: '2.24'
|
|
66
|
+
- !ruby/object:Gem::Dependency
|
|
67
|
+
name: reverse_markdown
|
|
68
|
+
requirement: !ruby/object:Gem::Requirement
|
|
69
|
+
requirements:
|
|
70
|
+
- - "~>"
|
|
71
|
+
- !ruby/object:Gem::Version
|
|
72
|
+
version: '3.0'
|
|
73
|
+
type: :runtime
|
|
74
|
+
prerelease: false
|
|
75
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
76
|
+
requirements:
|
|
77
|
+
- - "~>"
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: '3.0'
|
|
80
|
+
- !ruby/object:Gem::Dependency
|
|
81
|
+
name: activejob
|
|
82
|
+
requirement: !ruby/object:Gem::Requirement
|
|
83
|
+
requirements:
|
|
84
|
+
- - ">="
|
|
85
|
+
- !ruby/object:Gem::Version
|
|
86
|
+
version: '7.2'
|
|
87
|
+
- - "<"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '9'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '7.2'
|
|
97
|
+
- - "<"
|
|
98
|
+
- !ruby/object:Gem::Version
|
|
99
|
+
version: '9'
|
|
100
|
+
- !ruby/object:Gem::Dependency
|
|
101
|
+
name: minitest
|
|
102
|
+
requirement: !ruby/object:Gem::Requirement
|
|
103
|
+
requirements:
|
|
104
|
+
- - "~>"
|
|
105
|
+
- !ruby/object:Gem::Version
|
|
106
|
+
version: '5.0'
|
|
107
|
+
type: :development
|
|
108
|
+
prerelease: false
|
|
109
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
110
|
+
requirements:
|
|
111
|
+
- - "~>"
|
|
112
|
+
- !ruby/object:Gem::Version
|
|
113
|
+
version: '5.0'
|
|
114
|
+
- !ruby/object:Gem::Dependency
|
|
115
|
+
name: rake
|
|
116
|
+
requirement: !ruby/object:Gem::Requirement
|
|
117
|
+
requirements:
|
|
118
|
+
- - "~>"
|
|
119
|
+
- !ruby/object:Gem::Version
|
|
120
|
+
version: '13.0'
|
|
121
|
+
type: :development
|
|
122
|
+
prerelease: false
|
|
123
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
124
|
+
requirements:
|
|
125
|
+
- - "~>"
|
|
126
|
+
- !ruby/object:Gem::Version
|
|
127
|
+
version: '13.0'
|
|
128
|
+
description: 'A Rails engine that replaces per-app SEO/GEO code with one configuration
|
|
129
|
+
file and one layout line: meta tags, canonical folding, JSON-LD, crawler fallback
|
|
130
|
+
bodies, purpose-based AI crawler policy, robots.txt, sitemap.xml, llms.txt, Markdown
|
|
131
|
+
negotiation, IndexNow and OG images. GEO means Generative Engine Optimization, not
|
|
132
|
+
geolocation.'
|
|
133
|
+
email:
|
|
134
|
+
- theqwe2000@gmail.com
|
|
135
|
+
executables: []
|
|
136
|
+
extensions: []
|
|
137
|
+
extra_rdoc_files: []
|
|
138
|
+
files:
|
|
139
|
+
- AGENTS.md
|
|
140
|
+
- CHANGELOG.md
|
|
141
|
+
- LICENSE.txt
|
|
142
|
+
- README.md
|
|
143
|
+
- app/controllers/seo_geo/index_now_controller.rb
|
|
144
|
+
- app/controllers/seo_geo/llms_controller.rb
|
|
145
|
+
- app/controllers/seo_geo/og_images_controller.rb
|
|
146
|
+
- app/controllers/seo_geo/robots_controller.rb
|
|
147
|
+
- app/controllers/seo_geo/sitemaps_controller.rb
|
|
148
|
+
- app/jobs/seo_geo/index_now_job.rb
|
|
149
|
+
- app/views/seo_geo/fallback/_body.html.erb
|
|
150
|
+
- app/views/seo_geo/fallback/_faq.html.erb
|
|
151
|
+
- config/routes.rb
|
|
152
|
+
- lib/generators/seo_geo/install/install_generator.rb
|
|
153
|
+
- lib/generators/seo_geo/install/templates/home.yml.tt
|
|
154
|
+
- lib/generators/seo_geo/install/templates/initializer.rb.tt
|
|
155
|
+
- lib/seo_geo.rb
|
|
156
|
+
- lib/seo_geo/audit.rb
|
|
157
|
+
- lib/seo_geo/audit/checks.rb
|
|
158
|
+
- lib/seo_geo/audit/html_document.rb
|
|
159
|
+
- lib/seo_geo/audit/report.rb
|
|
160
|
+
- lib/seo_geo/audit/runner.rb
|
|
161
|
+
- lib/seo_geo/audit/static_scan.rb
|
|
162
|
+
- lib/seo_geo/bot_verifier.rb
|
|
163
|
+
- lib/seo_geo/configuration.rb
|
|
164
|
+
- lib/seo_geo/controller.rb
|
|
165
|
+
- lib/seo_geo/crawler_fallback.rb
|
|
166
|
+
- lib/seo_geo/crawlers.rb
|
|
167
|
+
- lib/seo_geo/engine.rb
|
|
168
|
+
- lib/seo_geo/index_now.rb
|
|
169
|
+
- lib/seo_geo/json_ld.rb
|
|
170
|
+
- lib/seo_geo/llms_txt.rb
|
|
171
|
+
- lib/seo_geo/markdown/document.rb
|
|
172
|
+
- lib/seo_geo/markdown/negotiation.rb
|
|
173
|
+
- lib/seo_geo/markdown/path_suffix.rb
|
|
174
|
+
- lib/seo_geo/markdownable.rb
|
|
175
|
+
- lib/seo_geo/meta.rb
|
|
176
|
+
- lib/seo_geo/model.rb
|
|
177
|
+
- lib/seo_geo/og_image/card.html.erb
|
|
178
|
+
- lib/seo_geo/og_image/ferrum_backend.rb
|
|
179
|
+
- lib/seo_geo/og_image/renderer.rb
|
|
180
|
+
- lib/seo_geo/page.rb
|
|
181
|
+
- lib/seo_geo/path_match.rb
|
|
182
|
+
- lib/seo_geo/publication.rb
|
|
183
|
+
- lib/seo_geo/robots.rb
|
|
184
|
+
- lib/seo_geo/robots/evaluator.rb
|
|
185
|
+
- lib/seo_geo/robots_directives.rb
|
|
186
|
+
- lib/seo_geo/robots_path.rb
|
|
187
|
+
- lib/seo_geo/rspec.rb
|
|
188
|
+
- lib/seo_geo/safe_regexp.rb
|
|
189
|
+
- lib/seo_geo/sitemap/registry.rb
|
|
190
|
+
- lib/seo_geo/sitemap/xml.rb
|
|
191
|
+
- lib/seo_geo/testing.rb
|
|
192
|
+
- lib/seo_geo/testing/environment.rb
|
|
193
|
+
- lib/seo_geo/undeclared_host.rb
|
|
194
|
+
- lib/seo_geo/version.rb
|
|
195
|
+
- lib/tasks/seo_geo.rake
|
|
196
|
+
- llms.txt
|
|
197
|
+
homepage: https://github.com/seunghan91/seo_geo
|
|
198
|
+
licenses:
|
|
199
|
+
- MIT
|
|
200
|
+
metadata:
|
|
201
|
+
changelog_uri: https://github.com/seunghan91/seo_geo/blob/main/CHANGELOG.md
|
|
202
|
+
bug_tracker_uri: https://github.com/seunghan91/seo_geo/issues
|
|
203
|
+
documentation_uri: https://github.com/seunghan91/seo_geo#readme
|
|
204
|
+
source_code_uri: https://github.com/seunghan91/seo_geo
|
|
205
|
+
rubygems_mfa_required: 'true'
|
|
206
|
+
rdoc_options: []
|
|
207
|
+
require_paths:
|
|
208
|
+
- lib
|
|
209
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
210
|
+
requirements:
|
|
211
|
+
- - ">="
|
|
212
|
+
- !ruby/object:Gem::Version
|
|
213
|
+
version: '3.2'
|
|
214
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
215
|
+
requirements:
|
|
216
|
+
- - ">="
|
|
217
|
+
- !ruby/object:Gem::Version
|
|
218
|
+
version: '0'
|
|
219
|
+
requirements: []
|
|
220
|
+
rubygems_version: 3.6.2
|
|
221
|
+
specification_version: 4
|
|
222
|
+
summary: 'SEO and GEO (AI search visibility) for Rails: meta, JSON-LD, robots, sitemap,
|
|
223
|
+
llms.txt, Markdown'
|
|
224
|
+
test_files: []
|