meta-tags 2.22.3 → 2.24.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +83 -0
- data/README.md +191 -60
- data/SECURITY.md +40 -0
- data/lib/generators/meta_tags/install_generator.rb +5 -0
- data/lib/generators/meta_tags/templates/config/initializers/meta_tags.rb +16 -5
- data/lib/meta_tags/configuration.rb +31 -10
- data/lib/meta_tags/content_tag.rb +3 -4
- data/lib/meta_tags/controller_helper.rb +11 -8
- data/lib/meta_tags/meta_tags_collection.rb +123 -50
- data/lib/meta_tags/railtie.rb +5 -0
- data/lib/meta_tags/renderer.rb +124 -84
- data/lib/meta_tags/tag.rb +10 -8
- data/lib/meta_tags/text_normalizer.rb +54 -40
- data/lib/meta_tags/version.rb +1 -1
- data/lib/meta_tags/view_helper.rb +65 -75
- data/lib/meta_tags.rb +6 -2
- data/sig/{lib/_internal/rails.rbs → _private/rails_support.rbs} +5 -19
- data/sig/lib/meta_tags/configuration.rbs +5 -3
- data/sig/lib/meta_tags/controller_helper.rbs +1 -1
- data/sig/lib/meta_tags/meta_tags_collection.rbs +9 -3
- data/sig/lib/meta_tags/rails_interfaces.rbs +15 -0
- data/sig/lib/meta_tags/renderer.rbs +11 -7
- data/sig/lib/meta_tags/tag.rbs +1 -1
- data/sig/lib/meta_tags/view_helper.rbs +9 -37
- data/sig/lib/meta_tags.rbs +5 -1
- data.tar.gz.sig +0 -0
- metadata +22 -5
- metadata.gz.sig +0 -0
data/README.md
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
# MetaTags:
|
|
1
|
+
# MetaTags: Rails helpers for SEO metadata, sharing, canonical URLs, and robots
|
|
2
2
|
|
|
3
3
|
[](https://github.com/kpumuk/meta-tags/actions/workflows/tests.yml)
|
|
4
4
|
[](https://badge.fury.io/rb/meta-tags)
|
|
5
|
+
[](https://scorecard.dev/viewer/?uri=github.com/kpumuk/meta-tags)
|
|
5
6
|
[](https://github.com/testdouble/standard)
|
|
6
7
|
[](https://badge.fury.io/rb/meta-tags)
|
|
7
8
|
[](https://github.com/kpumuk/meta-tags/blob/main/CHANGELOG.md)
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
MetaTags helps Ruby on Rails applications render HTML head metadata such as titles, descriptions, canonical links, robots directives, Open Graph tags, X card tags, and hreflang links.
|
|
11
|
+
|
|
12
|
+
It supports the metadata layer of search engine optimization (SEO), especially for titles, descriptions, canonicalization, robots directives, and social sharing previews.
|
|
10
13
|
|
|
11
14
|
## Ruby on Rails
|
|
12
15
|
|
|
@@ -15,6 +18,9 @@ The MetaTags main branch fully supports Ruby on Rails 6.1+ and is tested against
|
|
|
15
18
|
> [!NOTE]
|
|
16
19
|
> We no longer support Ruby versions older than 3.0 and Ruby on Rails older than 6.1 since they reached their end of life (see [Ruby](https://endoflife.date/ruby) and [Ruby on Rails](https://endoflife.date/rails)).
|
|
17
20
|
|
|
21
|
+
> [!IMPORTANT]
|
|
22
|
+
> MetaTags manages HTML head metadata. It does not generate structured data / JSON-LD, `robots.txt`, sitemaps, internal links, or page content.
|
|
23
|
+
|
|
18
24
|
## Installation
|
|
19
25
|
|
|
20
26
|
Add the "meta-tags" gem to your `Gemfile`.
|
|
@@ -27,7 +33,7 @@ And run `bundle install` command.
|
|
|
27
33
|
|
|
28
34
|
## Configuration
|
|
29
35
|
|
|
30
|
-
MetaTags
|
|
36
|
+
MetaTags ships with practical defaults for truncation and rendering. You can change them to match your application. Legacy fields such as `keywords` are still supported for compatibility, but they are not modern search requirements.
|
|
31
37
|
|
|
32
38
|
To override the defaults, create an initializer `config/initializers/meta_tags.rb` using the following command:
|
|
33
39
|
|
|
@@ -35,6 +41,25 @@ To override the defaults, create an initializer `config/initializers/meta_tags.r
|
|
|
35
41
|
rails generate meta_tags:install
|
|
36
42
|
```
|
|
37
43
|
|
|
44
|
+
When a truncation limit is reached, arrays passed to `title` or `keywords` can
|
|
45
|
+
either partially truncate the last item or stop at item boundaries. Set
|
|
46
|
+
`config.truncate_array_items_at_boundaries = true` to preserve whole items for
|
|
47
|
+
multi-item arrays. Single-item arrays are still truncated normally.
|
|
48
|
+
|
|
49
|
+
Symbols in nested custom tag arrays are literal values in MetaTags 2.x.
|
|
50
|
+
MetaTags 3.0 will use them to look up normalized top-level tags. You can turn
|
|
51
|
+
on this behavior now. Until then, each nested array that contains a direct
|
|
52
|
+
Symbol value emits a deprecation warning:
|
|
53
|
+
|
|
54
|
+
```ruby
|
|
55
|
+
MetaTags.configure do |config|
|
|
56
|
+
config.resolve_symbolic_references_in_arrays = true
|
|
57
|
+
end
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
When this option is on, use Strings for literal array values. MetaTags does not
|
|
61
|
+
render a tag when a Symbol has no match.
|
|
62
|
+
|
|
38
63
|
By default, meta tags are rendered with the key `name`. However, some meta tags are required to use `property` instead (like Facebook Open Graph object). The MetaTags gem allows you to configure which tags to render with the `property` attribute. The pre-configured list includes all possible Facebook Open Graph object types by default, but you can add your own in case you need it.
|
|
39
64
|
|
|
40
65
|
## MetaTags Usage
|
|
@@ -76,7 +101,6 @@ You can define the following instance variables:
|
|
|
76
101
|
```ruby
|
|
77
102
|
@page_title = "Member Login"
|
|
78
103
|
@page_description = "Member login page."
|
|
79
|
-
@page_keywords = "Site, Login, Members"
|
|
80
104
|
```
|
|
81
105
|
|
|
82
106
|
Also, you could use the `set_meta_tags` method to define all meta tags simultaneously:
|
|
@@ -84,8 +108,7 @@ Also, you could use the `set_meta_tags` method to define all meta tags simultane
|
|
|
84
108
|
```ruby
|
|
85
109
|
set_meta_tags(
|
|
86
110
|
title: "Member Login",
|
|
87
|
-
description: "Member login page."
|
|
88
|
-
keywords: "Site, Login, Members"
|
|
111
|
+
description: "Member login page."
|
|
89
112
|
)
|
|
90
113
|
```
|
|
91
114
|
|
|
@@ -98,7 +121,6 @@ To set meta tags, you can use the following methods:
|
|
|
98
121
|
```erb
|
|
99
122
|
<% title "Member Login" %>
|
|
100
123
|
<% description "Member login page." %>
|
|
101
|
-
<% keywords "Site, Login, Members" %>
|
|
102
124
|
<% nofollow %>
|
|
103
125
|
<% noindex %>
|
|
104
126
|
<% refresh 3 %>
|
|
@@ -110,8 +132,7 @@ Also, the `set_meta_tags` method exists:
|
|
|
110
132
|
<%
|
|
111
133
|
set_meta_tags(
|
|
112
134
|
title: "Member Login",
|
|
113
|
-
description: "Member login page."
|
|
114
|
-
keywords: "Site, Login, Members"
|
|
135
|
+
description: "Member login page."
|
|
115
136
|
)
|
|
116
137
|
%>
|
|
117
138
|
```
|
|
@@ -147,14 +168,14 @@ If you want to set the title and display another text, use this:
|
|
|
147
168
|
|
|
148
169
|
### Allowed options for `display_meta_tags` and `set_meta_tags` methods
|
|
149
170
|
|
|
150
|
-
Use these options to customize the
|
|
171
|
+
Use these options to customize the generated tags:
|
|
151
172
|
|
|
152
173
|
| Option | Description |
|
|
153
174
|
| -------------- | ------------------------------------------------------------------------------------------------------------------- |
|
|
154
175
|
| `:site` | Site title |
|
|
155
176
|
| `:title` | Page title |
|
|
156
177
|
| `:description` | Page description |
|
|
157
|
-
| `:keywords` |
|
|
178
|
+
| `:keywords` | Legacy keywords meta tag for compatibility; ignored by Google Search and Bing web search |
|
|
158
179
|
| `:charset` | Page character set |
|
|
159
180
|
| `:prefix` | Text between site name and separator |
|
|
160
181
|
| `:separator` | Text used to separate the website name from the page title |
|
|
@@ -166,10 +187,13 @@ Use these options to customize the title format:
|
|
|
166
187
|
| `:nofollow` | Add nofollow meta tag; when true, "robots" will be used; accepts a string with a robot name or an array of strings |
|
|
167
188
|
| `:follow` | Add follow meta tag; when true, "robots" will be used; accepts a string with a robot name or an array of strings |
|
|
168
189
|
| `:noarchive` | Add noarchive meta tag; when true, "robots" will be used; accepts a string with a robot name or an array of strings |
|
|
190
|
+
| `:robots` | Add custom directives to the `robots` meta tag (Hash) |
|
|
191
|
+
| `:googlebot` | Add custom directives to the `googlebot` meta tag (Hash) |
|
|
192
|
+
| `:bingbot` | Add custom directives to the `bingbot` meta tag (Hash) |
|
|
169
193
|
| `:canonical` | Add canonical link tag |
|
|
170
|
-
| `:prev` | Add prev link tag
|
|
171
|
-
| `:next` | Add next link tag
|
|
172
|
-
| `:image_src` | Add image_src
|
|
194
|
+
| `:prev` | Add legacy prev pagination link tag |
|
|
195
|
+
| `:next` | Add legacy next pagination link tag |
|
|
196
|
+
| `:image_src` | Add legacy image_src share hint |
|
|
173
197
|
| `:og` | Add Open Graph tags (Hash) |
|
|
174
198
|
| `:twitter` | Add Twitter tags (Hash) |
|
|
175
199
|
| `:refresh` | Refresh interval and optionally URL to redirect to |
|
|
@@ -196,7 +220,7 @@ set_meta_tags title: ["part1", "part2"], reverse: true, site: "site"
|
|
|
196
220
|
# part2 | part1 | site
|
|
197
221
|
```
|
|
198
222
|
|
|
199
|
-
|
|
223
|
+
If you still need the legacy `keywords` tag, values can be passed as a string of comma-separated values or as an array:
|
|
200
224
|
|
|
201
225
|
```ruby
|
|
202
226
|
set_meta_tags keywords: ["tag1", "tag2"]
|
|
@@ -266,7 +290,6 @@ def default_meta_tags
|
|
|
266
290
|
{
|
|
267
291
|
title: "Member Login",
|
|
268
292
|
description: "Member login page.",
|
|
269
|
-
keywords: "Site, Login, Members",
|
|
270
293
|
separator: "—".html_safe
|
|
271
294
|
}
|
|
272
295
|
end
|
|
@@ -289,11 +312,15 @@ And in your pjax templates:
|
|
|
289
312
|
<% end %>
|
|
290
313
|
```
|
|
291
314
|
|
|
292
|
-
##
|
|
315
|
+
## Search and Sharing Metadata
|
|
316
|
+
|
|
317
|
+
These tags still matter for search snippets, canonicalization, robots directives, and social sharing. They are only one part of modern SEO. You should combine them with good page content, internal links, structured data, sitemaps, and crawl controls where appropriate.
|
|
293
318
|
|
|
294
319
|
### Titles
|
|
295
320
|
|
|
296
|
-
Page titles
|
|
321
|
+
Page titles help browsers, social previews, and search engines understand the page. Use unique, descriptive titles that match the visible page content.
|
|
322
|
+
|
|
323
|
+
<!-- executable-example: titles -->
|
|
297
324
|
|
|
298
325
|
```ruby
|
|
299
326
|
set_meta_tags title: "Member Login"
|
|
@@ -304,48 +331,58 @@ set_meta_tags site: "Site Title", title: "Member Login", reverse: true
|
|
|
304
331
|
# <title>Member Login | Site Title</title>
|
|
305
332
|
```
|
|
306
333
|
|
|
307
|
-
|
|
334
|
+
Google does not publish a fixed title length. Keep titles concise and informative; search results may truncate them based on available width.
|
|
308
335
|
|
|
309
336
|
Further reading:
|
|
310
337
|
|
|
311
338
|
- [Title Tag](https://moz.com/learn/seo/title-tag)
|
|
339
|
+
- [Google Search Central: title links](https://developers.google.com/search/docs/appearance/title-link)
|
|
312
340
|
|
|
313
341
|
### Description
|
|
314
342
|
|
|
315
|
-
Description meta tags
|
|
343
|
+
Description meta tags help search engines generate snippets, but search engines may also use visible page text instead. Write a short summary that matches the page.
|
|
316
344
|
|
|
317
345
|
Below is an example of how to set a description tag using Ruby:
|
|
318
346
|
|
|
347
|
+
<!-- executable-example: description -->
|
|
348
|
+
|
|
319
349
|
```ruby
|
|
320
350
|
set_meta_tags description: "This is a sample description"
|
|
321
351
|
# <meta name="description" content="This is a sample description">
|
|
322
352
|
```
|
|
323
353
|
|
|
324
|
-
|
|
354
|
+
Google does not publish a fixed meta description length. Make the description long enough to be useful and specific, not long enough to hit an arbitrary character count.
|
|
325
355
|
|
|
326
356
|
Further reading:
|
|
327
357
|
|
|
328
358
|
- [Meta Description](https://moz.com/learn/seo/meta-description)
|
|
329
359
|
- [How Long Should Your Meta Description Be? (2018 Edition)](https://moz.com/blog/how-long-should-your-meta-description-be-2018)
|
|
360
|
+
- [Google Search Central: control your snippets in search results](https://developers.google.com/search/docs/appearance/snippet)
|
|
330
361
|
|
|
331
362
|
### Keywords
|
|
332
363
|
|
|
333
|
-
|
|
364
|
+
The `keywords` tag is a legacy feature. MetaTags still supports it for backwards compatibility and for systems that still read it, but it is not a modern web SEO signal.
|
|
365
|
+
|
|
366
|
+
<!-- executable-example: keywords -->
|
|
334
367
|
|
|
335
368
|
```ruby
|
|
336
369
|
set_meta_tags keywords: %w[keyword1 keyword2 keyword3]
|
|
337
370
|
# <meta name="keywords" content="keyword1, keyword2, keyword3">
|
|
338
371
|
```
|
|
339
372
|
|
|
340
|
-
It is recommended to keep the length of the keywords tag under **255 characters** or **20 words**.
|
|
341
|
-
|
|
342
373
|
> [!NOTE]
|
|
343
|
-
>
|
|
374
|
+
> Google Search ignores the `keywords` meta tag, and Bing web search has long treated it the same way. Use this tag only if you have your own downstream consumer for it.
|
|
375
|
+
|
|
376
|
+
Further reading:
|
|
377
|
+
|
|
378
|
+
- [Google Search Central: meta tags Google supports](https://developers.google.com/search/docs/crawling-indexing/special-tags)
|
|
344
379
|
|
|
345
380
|
### Noindex
|
|
346
381
|
|
|
347
382
|
By using the noindex meta tag, you can signal to search engines not to include specific pages in their indexes.
|
|
348
383
|
|
|
384
|
+
<!-- executable-example: noindex -->
|
|
385
|
+
|
|
349
386
|
```ruby
|
|
350
387
|
set_meta_tags noindex: true
|
|
351
388
|
# <meta name="robots" content="noindex">
|
|
@@ -353,16 +390,19 @@ set_meta_tags noindex: "googlebot"
|
|
|
353
390
|
# <meta name="googlebot" content="noindex">
|
|
354
391
|
```
|
|
355
392
|
|
|
356
|
-
This is useful for pages like login, password reset,
|
|
393
|
+
This is useful for pages like login, password reset, cart, account settings, or internal search results.
|
|
357
394
|
|
|
358
395
|
Further reading:
|
|
359
396
|
|
|
360
397
|
- [Blocking Google](http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=93708)
|
|
361
398
|
- [Using meta tags to block access to your site](http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=93710)
|
|
399
|
+
- [Google Search Central: robots meta tag and X-Robots-Tag](https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag)
|
|
362
400
|
|
|
363
401
|
### Index
|
|
364
402
|
|
|
365
|
-
|
|
403
|
+
In most cases, you do not need to emit `index` explicitly because it is already the default for crawlable pages.
|
|
404
|
+
|
|
405
|
+
<!-- executable-example: index -->
|
|
366
406
|
|
|
367
407
|
```ruby
|
|
368
408
|
set_meta_tags index: true
|
|
@@ -373,6 +413,8 @@ set_meta_tags index: true
|
|
|
373
413
|
|
|
374
414
|
Nofollow meta tags tell a search engine not to follow the links on a specific page. It is entirely possible that a robot might find the same links on another page without a nofollow attribute, perhaps on another site, and still arrive at your undesired page.
|
|
375
415
|
|
|
416
|
+
<!-- executable-example: nofollow -->
|
|
417
|
+
|
|
376
418
|
```ruby
|
|
377
419
|
set_meta_tags nofollow: true
|
|
378
420
|
# <meta name="robots" content="nofollow">
|
|
@@ -382,12 +424,15 @@ set_meta_tags nofollow: "googlebot"
|
|
|
382
424
|
|
|
383
425
|
Further reading:
|
|
384
426
|
|
|
385
|
-
- [About rel="nofollow"](
|
|
427
|
+
- [About rel="nofollow"](https://developers.google.com/search/docs/crawling-indexing/qualify-outbound-links)
|
|
386
428
|
- [Meta tags](http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=79812)
|
|
429
|
+
- [Google Search Central: robots meta tag and X-Robots-Tag](https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag)
|
|
387
430
|
|
|
388
431
|
### Follow
|
|
389
432
|
|
|
390
|
-
You can use
|
|
433
|
+
You can use `follow` with `noindex` if you need that combination, but most pages do not need an explicit `follow` tag because it is also the default behavior.
|
|
434
|
+
|
|
435
|
+
<!-- executable-example: follow -->
|
|
391
436
|
|
|
392
437
|
```ruby
|
|
393
438
|
set_meta_tags noindex: true, follow: true
|
|
@@ -396,12 +441,47 @@ set_meta_tags noindex: true, follow: true
|
|
|
396
441
|
|
|
397
442
|
This tag will prevent search engines from indexing this specific page, but it will still allow them to crawl and index the remaining pages on your website.
|
|
398
443
|
|
|
444
|
+
### Robots
|
|
445
|
+
|
|
446
|
+
Use the `robots`, `googlebot`, and `bingbot` hashes when you need directives beyond `index`, `noindex`, `follow`, `nofollow`, and `noarchive`.
|
|
447
|
+
|
|
448
|
+
This is useful for directives such as `max-snippet`, `max-video-preview`, and `unavailable_after`.
|
|
449
|
+
|
|
450
|
+
<!-- executable-example: robots -->
|
|
451
|
+
|
|
452
|
+
```ruby
|
|
453
|
+
set_meta_tags robots: {
|
|
454
|
+
"max-snippet" => -1,
|
|
455
|
+
"max-video-preview" => -1
|
|
456
|
+
}
|
|
457
|
+
# <meta name="robots" content="max-snippet:-1, max-video-preview:-1">
|
|
458
|
+
|
|
459
|
+
set_meta_tags googlebot: {
|
|
460
|
+
unavailable_after: "2026-12-31"
|
|
461
|
+
}
|
|
462
|
+
# <meta name="googlebot" content="unavailable_after:2026-12-31">
|
|
463
|
+
|
|
464
|
+
set_meta_tags bingbot: {
|
|
465
|
+
"max-image-preview" => "large"
|
|
466
|
+
}
|
|
467
|
+
# <meta name="bingbot" content="max-image-preview:large">
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
These hashes are merged with the existing robots helpers, so `noindex`, `nofollow`, and similar directives still render first for the same meta tag.
|
|
471
|
+
|
|
472
|
+
Further reading:
|
|
473
|
+
|
|
474
|
+
- [Google Search Central: robots meta tag and X-Robots-Tag](https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag)
|
|
475
|
+
- [Bing Webmaster Guidelines: robots meta tag support](https://www.bing.com/webmasters/help/which-robots-metatags-does-bing-support-5198d240)
|
|
476
|
+
|
|
399
477
|
### Canonical URL
|
|
400
478
|
|
|
401
|
-
Canonical link elements
|
|
479
|
+
Canonical link elements help search engines consolidate duplicate or near-duplicate URLs under one preferred URL. They are a signal, not a guarantee.
|
|
402
480
|
|
|
403
481
|
> [!NOTE]
|
|
404
|
-
> If
|
|
482
|
+
> If your goal is duplicate consolidation, prefer a canonical URL over `noindex`. If you do not want to mix canonical with `noindex`, set `MetaTags.config.skip_canonical_links_on_noindex = true`.
|
|
483
|
+
|
|
484
|
+
<!-- executable-example: canonical -->
|
|
405
485
|
|
|
406
486
|
```ruby
|
|
407
487
|
set_meta_tags canonical: "http://yoursite.com/canonical/url"
|
|
@@ -412,22 +492,25 @@ Further reading:
|
|
|
412
492
|
|
|
413
493
|
- [About rel="canonical"](http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=139394)
|
|
414
494
|
- [Canonicalization](http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=139066)
|
|
495
|
+
- [Google Search Central: canonicalization and duplicate URLs](https://developers.google.com/search/docs/crawling-indexing/consolidate-duplicate-urls)
|
|
415
496
|
|
|
416
497
|
### Icon
|
|
417
498
|
|
|
418
499
|
A favicon (short for Favorite icon), also known as a shortcut icon, website icon, tab icon, or bookmark icon, is a file containing one or more small icons, most commonly 16x16 pixels, associated with a particular website or web page.
|
|
419
500
|
|
|
501
|
+
<!-- executable-example: icons -->
|
|
502
|
+
|
|
420
503
|
```ruby
|
|
421
504
|
set_meta_tags icon: "/favicon.ico"
|
|
422
|
-
# <link rel="icon"
|
|
423
|
-
set_meta_tags icon: "/favicon.png", type: "image/png"
|
|
424
|
-
# <link rel="icon"
|
|
505
|
+
# <link rel="icon" type="image/x-icon" href="/favicon.ico">
|
|
506
|
+
set_meta_tags icon: {href: "/favicon.png", type: "image/png"}
|
|
507
|
+
# <link rel="icon" type="image/png" href="/favicon.png">
|
|
425
508
|
set_meta_tags icon: [
|
|
426
509
|
{href: "/images/icons/icon_96.png", sizes: "32x32 96x96", type: "image/png"},
|
|
427
510
|
{href: "/images/icons/icon_itouch_precomp_32.png", rel: "apple-touch-icon-precomposed", sizes: "32x32", type: "image/png"}
|
|
428
511
|
]
|
|
429
|
-
# <link rel="icon" href="/images/icons/icon_96.png"
|
|
430
|
-
# <link rel="apple-touch-icon-precomposed" href="/images/icons/icon_itouch_precomp_32.png"
|
|
512
|
+
# <link rel="icon" type="image/png" href="/images/icons/icon_96.png" sizes="32x32 96x96">
|
|
513
|
+
# <link rel="apple-touch-icon-precomposed" type="image/png" href="/images/icons/icon_itouch_precomp_32.png" sizes="32x32">
|
|
431
514
|
```
|
|
432
515
|
|
|
433
516
|
Further reading:
|
|
@@ -439,6 +522,8 @@ Further reading:
|
|
|
439
522
|
|
|
440
523
|
Alternate link elements tell a search engine when there is content that's translated or targeted to users in a certain region.
|
|
441
524
|
|
|
525
|
+
<!-- executable-example: alternate -->
|
|
526
|
+
|
|
442
527
|
```ruby
|
|
443
528
|
set_meta_tags alternate: {"fr" => "http://yoursite.fr/alternate/url"}
|
|
444
529
|
# <link rel="alternate" href="http://yoursite.fr/alternate/url" hreflang="fr">
|
|
@@ -467,7 +552,9 @@ Further reading:
|
|
|
467
552
|
|
|
468
553
|
### Pagination links
|
|
469
554
|
|
|
470
|
-
Previous and next links
|
|
555
|
+
Previous and next links can describe a paginated sequence for browsers, feed readers, or custom consumers that still read them. Google no longer uses `rel="prev"` and `rel="next"` as an indexing signal, so treat them as optional interoperability metadata, not core SEO guidance.
|
|
556
|
+
|
|
557
|
+
<!-- executable-example: pagination -->
|
|
471
558
|
|
|
472
559
|
```ruby
|
|
473
560
|
set_meta_tags prev: "http://yoursite.com/url?page=1"
|
|
@@ -478,12 +565,14 @@ set_meta_tags next: "http://yoursite.com/url?page=3"
|
|
|
478
565
|
|
|
479
566
|
Further reading:
|
|
480
567
|
|
|
481
|
-
- [Pagination](
|
|
482
|
-
- [
|
|
568
|
+
- [Pagination with rel="next" and rel="prev"](https://developers.google.com/search/blog/2011/09/pagination-with-relnext-and-relprev)
|
|
569
|
+
- [Google Search Central: pagination, incremental page loading, and infinite scroll](https://developers.google.com/search/docs/specialty/ecommerce/pagination-and-incremental-page-loading)
|
|
483
570
|
|
|
484
571
|
### image_src links
|
|
485
572
|
|
|
486
|
-
|
|
573
|
+
`image_src` is a legacy share hint. Modern social sharing generally relies on Open Graph images and platform-specific card tags instead.
|
|
574
|
+
|
|
575
|
+
<!-- executable-example: image-src -->
|
|
487
576
|
|
|
488
577
|
```ruby
|
|
489
578
|
set_meta_tags image_src: "http://yoursite.com/icons/icon_32.png"
|
|
@@ -492,22 +581,28 @@ set_meta_tags image_src: "http://yoursite.com/icons/icon_32.png"
|
|
|
492
581
|
|
|
493
582
|
### amphtml links
|
|
494
583
|
|
|
495
|
-
|
|
584
|
+
If your application still serves AMP pages, you can link the AMP version from the canonical page with `amphtml`. This is an optional legacy integration, not a general SEO requirement.
|
|
585
|
+
|
|
586
|
+
In a routed Rails view, you can generate the absolute URL with
|
|
587
|
+
`url_for(format: :amp, only_path: false)`.
|
|
588
|
+
|
|
589
|
+
<!-- executable-example: amphtml -->
|
|
496
590
|
|
|
497
591
|
```ruby
|
|
498
|
-
set_meta_tags amphtml:
|
|
592
|
+
set_meta_tags amphtml: "https://www.example.com/document.amp"
|
|
499
593
|
# <link rel="amphtml" href="https://www.example.com/document.amp">
|
|
500
594
|
```
|
|
501
595
|
|
|
502
596
|
To link back to the normal version, use the `canonical` tag.
|
|
503
597
|
|
|
504
|
-
- [
|
|
505
|
-
- [Make Your Page Discoverable](https://www.ampproject.org/docs/guides/discovery)
|
|
598
|
+
- [AMP documentation](https://amp.dev/documentation/)
|
|
506
599
|
|
|
507
600
|
### Manifest links
|
|
508
601
|
|
|
509
602
|
By including the `rel="manifest"` attribute in the `<link>` element of an HTML page, you can specify the location of the manifest file that describes the web application. This allows the browser to understand that the web page is an application and to provide features like offline access and the ability to add the application to the home screen of a mobile device.
|
|
510
603
|
|
|
604
|
+
<!-- executable-example: manifest -->
|
|
605
|
+
|
|
511
606
|
```ruby
|
|
512
607
|
set_meta_tags manifest: "manifest.json"
|
|
513
608
|
# <link rel="manifest" href="manifest.json">
|
|
@@ -519,11 +614,13 @@ set_meta_tags manifest: "manifest.json"
|
|
|
519
614
|
|
|
520
615
|
Meta refresh is a method of instructing a web browser to automatically refresh the current web page or frame after a given time interval. It is also possible to instruct the browser to fetch a different URL when the page is refreshed, by including the alternative URL in the content parameter. By setting the refresh time interval to zero (or a very low value), this allows meta refresh to be used as a method of URL redirection.
|
|
521
616
|
|
|
617
|
+
<!-- executable-example: refresh -->
|
|
618
|
+
|
|
522
619
|
```ruby
|
|
523
620
|
set_meta_tags refresh: 5
|
|
524
|
-
# <meta
|
|
621
|
+
# <meta http-equiv="refresh" content="5">
|
|
525
622
|
set_meta_tags refresh: "5;url=http://example.com"
|
|
526
|
-
# <meta content="5;url=http://example.com"
|
|
623
|
+
# <meta http-equiv="refresh" content="5;url=http://example.com">
|
|
527
624
|
```
|
|
528
625
|
|
|
529
626
|
Further reading:
|
|
@@ -535,23 +632,27 @@ Further reading:
|
|
|
535
632
|
|
|
536
633
|
Open Search is a link element used to describe a search engine in a standard and accessible format.
|
|
537
634
|
|
|
635
|
+
<!-- executable-example: open-search -->
|
|
636
|
+
|
|
538
637
|
```ruby
|
|
539
638
|
set_meta_tags open_search: {
|
|
540
639
|
title: "Open Search",
|
|
541
640
|
href: "/opensearch.xml"
|
|
542
641
|
}
|
|
543
|
-
# <link
|
|
642
|
+
# <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="Open Search">
|
|
544
643
|
```
|
|
545
644
|
|
|
546
645
|
Further reading:
|
|
547
646
|
|
|
548
|
-
- [OpenSearch specs](
|
|
647
|
+
- [OpenSearch specs](https://github.com/dewitt/opensearch/blob/master/opensearch-1-1-draft-6.md)
|
|
549
648
|
- [OpenSearch wiki](http://en.wikipedia.org/wiki/OpenSearch)
|
|
550
649
|
|
|
551
650
|
### Hashes
|
|
552
651
|
|
|
553
652
|
Any namespace can be created by simply passing a symbol name and a Hash. For example:
|
|
554
653
|
|
|
654
|
+
<!-- executable-example: hashes -->
|
|
655
|
+
|
|
555
656
|
```ruby
|
|
556
657
|
set_meta_tags foo: {
|
|
557
658
|
bar: "lorem",
|
|
@@ -559,14 +660,20 @@ set_meta_tags foo: {
|
|
|
559
660
|
qux: "ipsum"
|
|
560
661
|
}
|
|
561
662
|
}
|
|
562
|
-
# <meta
|
|
563
|
-
# <meta
|
|
663
|
+
# <meta name="foo:bar" content="lorem">
|
|
664
|
+
# <meta name="foo:baz:qux" content="ipsum">
|
|
564
665
|
```
|
|
565
666
|
|
|
667
|
+
Arbitrary namespaces use the `name` attribute by default. To render `foo` and
|
|
668
|
+
its colon-delimited children with `property`, add `foo` to
|
|
669
|
+
`MetaTags.config.property_tags` in your initializer.
|
|
670
|
+
|
|
566
671
|
### Arrays
|
|
567
672
|
|
|
568
673
|
Repeated meta tags can be easily created by using an Array within a Hash. For example:
|
|
569
674
|
|
|
675
|
+
<!-- executable-example: arrays -->
|
|
676
|
+
|
|
570
677
|
```ruby
|
|
571
678
|
set_meta_tags og: {
|
|
572
679
|
image: ["http://example.com/rock.jpg", "http://example.com/rock2.jpg"]
|
|
@@ -579,6 +686,8 @@ set_meta_tags og: {
|
|
|
579
686
|
|
|
580
687
|
To turn your web pages into graph objects, you'll need to add Open Graph protocol `<meta>` tags to your webpages. The tags allow you to specify structured information about your web pages. The more information you provide, the more opportunities your web pages can be surfaced within Facebook today and in the future. Here's an example for a movie page:
|
|
581
688
|
|
|
689
|
+
<!-- executable-example: open-graph -->
|
|
690
|
+
|
|
582
691
|
```ruby
|
|
583
692
|
set_meta_tags og: {
|
|
584
693
|
title: "The Rock",
|
|
@@ -601,11 +710,13 @@ set_meta_tags og: {
|
|
|
601
710
|
|
|
602
711
|
Multiple images declared as an **array** (look at the `_` character):
|
|
603
712
|
|
|
713
|
+
<!-- executable-example: open-graph-images -->
|
|
714
|
+
|
|
604
715
|
```ruby
|
|
605
716
|
set_meta_tags og: {
|
|
606
717
|
title: "Two structured image properties",
|
|
607
718
|
type: "website",
|
|
608
|
-
url: "
|
|
719
|
+
url: "http://examples.opengraphprotocol.us/image-array.html",
|
|
609
720
|
image: [
|
|
610
721
|
{
|
|
611
722
|
_: "http://examples.opengraphprotocol.us/media/images/75.png",
|
|
@@ -632,6 +743,8 @@ set_meta_tags og: {
|
|
|
632
743
|
|
|
633
744
|
Article meta tags are supported too:
|
|
634
745
|
|
|
746
|
+
<!-- executable-example: article -->
|
|
747
|
+
|
|
635
748
|
```ruby
|
|
636
749
|
set_meta_tags article: {
|
|
637
750
|
published_time: "2013-09-17T05:59:00+01:00",
|
|
@@ -648,11 +761,15 @@ set_meta_tags article: {
|
|
|
648
761
|
Further reading:
|
|
649
762
|
|
|
650
763
|
- [Open Graph protocol](http://developers.facebook.com/docs/opengraph/)
|
|
764
|
+
- [Open Graph protocol](https://ogp.me/)
|
|
651
765
|
- [Must-Have Social Meta Tags for Twitter, Google+, Facebook and More](https://moz.com/blog/meta-data-templates-123)
|
|
766
|
+
- [X for Websites documentation](https://developer.x.com/en/docs/x-for-websites)
|
|
652
767
|
|
|
653
768
|
### Twitter Cards
|
|
654
769
|
|
|
655
|
-
|
|
770
|
+
X cards let links shared on X show richer previews. The metadata namespace is still `twitter:*`. Here is a simple summary card example:
|
|
771
|
+
|
|
772
|
+
<!-- executable-example: twitter -->
|
|
656
773
|
|
|
657
774
|
```ruby
|
|
658
775
|
set_meta_tags twitter: {
|
|
@@ -663,51 +780,61 @@ set_meta_tags twitter: {
|
|
|
663
780
|
# <meta name="twitter:site" content="@username">
|
|
664
781
|
```
|
|
665
782
|
|
|
666
|
-
|
|
783
|
+
If you already publish Open Graph tags, you can often keep the X-specific tags minimal. Many consumers fall back to supported Open Graph fields when X-specific fields are missing.
|
|
784
|
+
|
|
785
|
+
When you need to generate nested `twitter:image:*` tags, the `twitter:image` property is a string while sub-properties can be expressed as a `Hash` in MetaTags:
|
|
667
786
|
|
|
668
|
-
|
|
787
|
+
<!-- executable-example: twitter-image -->
|
|
669
788
|
|
|
670
789
|
```ruby
|
|
671
790
|
set_meta_tags twitter: {
|
|
672
|
-
card: "
|
|
791
|
+
card: "summary_large_image",
|
|
673
792
|
image: {
|
|
674
793
|
_: "http://example.com/1.png",
|
|
675
794
|
width: 100,
|
|
676
|
-
height: 100
|
|
795
|
+
height: 100,
|
|
796
|
+
alt: "Cover image"
|
|
677
797
|
}
|
|
678
798
|
}
|
|
679
|
-
# <meta name="twitter:card" content="
|
|
799
|
+
# <meta name="twitter:card" content="summary_large_image">
|
|
680
800
|
# <meta name="twitter:image" content="http://example.com/1.png">
|
|
681
801
|
# <meta name="twitter:image:width" content="100">
|
|
682
802
|
# <meta name="twitter:image:height" content="100">
|
|
803
|
+
# <meta name="twitter:image:alt" content="Cover image">
|
|
683
804
|
```
|
|
684
805
|
|
|
685
806
|
A special parameter `itemprop` can be used on an "anonymous" tag "\_" to generate the "itemprop" HTML attribute:
|
|
686
807
|
|
|
808
|
+
<!-- executable-example: twitter-itemprop -->
|
|
809
|
+
|
|
687
810
|
```ruby
|
|
688
811
|
set_meta_tags twitter: {
|
|
689
|
-
card: "
|
|
812
|
+
card: "summary_large_image",
|
|
690
813
|
image: {
|
|
691
814
|
_: "http://example.com/1.png",
|
|
692
815
|
width: 100,
|
|
693
816
|
height: 100,
|
|
817
|
+
alt: "Cover image",
|
|
694
818
|
itemprop: "image"
|
|
695
819
|
}
|
|
696
820
|
}
|
|
697
|
-
# <meta name="twitter:card" content="
|
|
821
|
+
# <meta name="twitter:card" content="summary_large_image">
|
|
698
822
|
# <meta name="twitter:image" content="http://example.com/1.png" itemprop="image">
|
|
699
823
|
# <meta name="twitter:image:width" content="100">
|
|
700
824
|
# <meta name="twitter:image:height" content="100">
|
|
825
|
+
# <meta name="twitter:image:alt" content="Cover image">
|
|
701
826
|
```
|
|
702
827
|
|
|
703
828
|
Further reading:
|
|
704
829
|
|
|
705
|
-
- [
|
|
830
|
+
- [X for Websites documentation](https://developer.x.com/en/docs/x-for-websites)
|
|
706
831
|
|
|
707
832
|
### App Links
|
|
708
833
|
|
|
709
834
|
App Links is an open cross-platform solution for deep linking to content in your mobile app. Here's an example of iOS app integration:
|
|
710
835
|
|
|
836
|
+
<!-- executable-example: app-links -->
|
|
837
|
+
|
|
711
838
|
```ruby
|
|
712
839
|
set_meta_tags al: {
|
|
713
840
|
ios: {
|
|
@@ -731,6 +858,8 @@ Starting from version 1.3.1, you can specify arbitrary meta tags, and they will
|
|
|
731
858
|
|
|
732
859
|
Example:
|
|
733
860
|
|
|
861
|
+
<!-- executable-example: custom-author -->
|
|
862
|
+
|
|
734
863
|
```ruby
|
|
735
864
|
set_meta_tags author: "Dmytro Shteflyuk"
|
|
736
865
|
# <meta name="author" content="Dmytro Shteflyuk">
|
|
@@ -738,6 +867,8 @@ set_meta_tags author: "Dmytro Shteflyuk"
|
|
|
738
867
|
|
|
739
868
|
You can also specify the value as an Array, and the values will be displayed as a list of `meta` tags:
|
|
740
869
|
|
|
870
|
+
<!-- executable-example: custom-author-array -->
|
|
871
|
+
|
|
741
872
|
```ruby
|
|
742
873
|
set_meta_tags author: ["Dmytro Shteflyuk", "John Doe"]
|
|
743
874
|
# <meta name="author" content="Dmytro Shteflyuk">
|