[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-7917":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":16,"forks30d":16,"starsTrendScore":17,"compositeScore":19,"rankGlobal":10,"rankLanguage":10,"license":20,"archived":21,"fork":21,"defaultBranch":22,"hasWiki":21,"hasPages":21,"topics":23,"createdAt":10,"pushedAt":10,"updatedAt":34,"readmeContent":35,"aiSummary":36,"trendingCount":16,"starSnapshotCount":16,"syncStatus":37,"lastSyncTime":38,"discoverSource":39},7917,"meta-tags","kpumuk\u002Fmeta-tags","kpumuk","Search Engine Optimization (SEO) for Ruby on Rails applications.","",null,"Ruby",2795,280,43,12,0,1,3,29.35,"MIT License",false,"main",[5,24,25,26,27,28,29,30,31,32,33],"opengraph","opengraph-tags","rails","ruby","search-engine-optimization","seo","seo-meta","seotools","twitter-cards","webmasters","2026-06-12 02:01:46","# MetaTags: Rails helpers for SEO metadata, sharing, canonical URLs, and robots\n\n[![Tests](https:\u002F\u002Fgithub.com\u002Fkpumuk\u002Fmeta-tags\u002Factions\u002Fworkflows\u002Ftests.yml\u002Fbadge.svg)](https:\u002F\u002Fgithub.com\u002Fkpumuk\u002Fmeta-tags\u002Factions\u002Fworkflows\u002Ftests.yml)\n[![Gem Version](https:\u002F\u002Fbadge.fury.io\u002Frb\u002Fmeta-tags.svg)](https:\u002F\u002Fbadge.fury.io\u002Frb\u002Fmeta-tags)\n[![OpenSSF Scorecard](https:\u002F\u002Fapi.scorecard.dev\u002Fprojects\u002Fgithub.com\u002Fkpumuk\u002Fmeta-tags\u002Fbadge)](https:\u002F\u002Fscorecard.dev\u002Fviewer\u002F?uri=github.com\u002Fkpumuk\u002Fmeta-tags)\n[![Ruby Style Guide](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fcode_style-standard-brightgreen.svg)](https:\u002F\u002Fgithub.com\u002Ftestdouble\u002Fstandard)\n[![Gem Downloads](https:\u002F\u002Fimg.shields.io\u002Fgem\u002Fdt\u002Fmeta-tags.svg)](https:\u002F\u002Fbadge.fury.io\u002Frb\u002Fmeta-tags)\n[![Changelog](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FChangelog-latest-blue.svg)](https:\u002F\u002Fgithub.com\u002Fkpumuk\u002Fmeta-tags\u002Fblob\u002Fmain\u002FCHANGELOG.md)\n\nMetaTags 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.\n\nIt supports the metadata layer of search engine optimization (SEO), especially for titles, descriptions, canonicalization, robots directives, and social sharing previews.\n\n## Ruby on Rails\n\nThe MetaTags main branch fully supports Ruby on Rails 6.1+ and is tested against all major Ruby on Rails releases.\n\n> [!NOTE]\n> 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:\u002F\u002Fendoflife.date\u002Fruby) and [Ruby on Rails](https:\u002F\u002Fendoflife.date\u002Frails)).\n\n> [!IMPORTANT]\n> MetaTags manages HTML head metadata. It does not generate structured data \u002F JSON-LD, `robots.txt`, sitemaps, internal links, or page content.\n\n## Installation\n\nAdd the \"meta-tags\" gem to your `Gemfile`.\n\n```ruby\ngem \"meta-tags\"\n```\n\nAnd run `bundle install` command.\n\n## Configuration\n\nMetaTags 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.\n\nTo override the defaults, create an initializer `config\u002Finitializers\u002Fmeta_tags.rb` using the following command:\n\n```bash\nrails generate meta_tags:install\n```\n\nWhen a truncation limit is reached, arrays passed to `title` or `keywords` can\neither partially truncate the last item or stop at item boundaries. Set\n`config.truncate_array_items_at_boundaries = true` to preserve whole items for\nmulti-item arrays. Single-item arrays are still truncated normally.\n\nBy 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.\n\n## MetaTags Usage\n\nFirst, add this code to your main layout:\n\n```erb\n\u003Chead>\n  \u003C%= display_meta_tags site: \"My website\" %>\n\u003C\u002Fhead>\n```\n\nThen, to set the page title, add this to each of your views (see below for other options):\n\n```erb\n\u003Ch1>\u003C%= title \"My page title\" %>\u003C\u002Fh1>\n```\n\nWhen views are rendered, the page title will be included in the right spots:\n\n```html\n\u003Chead>\n  \u003Ctitle>My website | My page title\u003C\u002Ftitle>\n\u003C\u002Fhead>\n\u003Cbody>\n  \u003Ch1>My page title\u003C\u002Fh1>\n\u003C\u002Fbody>\n```\n\nYou can find allowed options for the `display_meta_tags` method below.\n\n> [!IMPORTANT]\n> You **must** use `display_meta_tags` in the layout files to render the meta tags. In the views, you will instead use `set_meta_tags`, which accepts the same arguments but does not render anything in the place where it is called.\n\n### Using MetaTags in controller\n\nYou can define the following instance variables:\n\n```ruby\n@page_title = \"Member Login\"\n@page_description = \"Member login page.\"\n```\n\nAlso, you could use the `set_meta_tags` method to define all meta tags simultaneously:\n\n```ruby\nset_meta_tags(\n  title: \"Member Login\",\n  description: \"Member login page.\"\n)\n```\n\nYou can find the allowed options for the `set_meta_tags` method below.\n\n### Using MetaTags in view\n\nTo set meta tags, you can use the following methods:\n\n```erb\n\u003C% title \"Member Login\" %>\n\u003C% description \"Member login page.\" %>\n\u003C% nofollow %>\n\u003C% noindex %>\n\u003C% refresh 3 %>\n```\n\nAlso, the `set_meta_tags` method exists:\n\n```erb\n\u003C%\n  set_meta_tags(\n    title: \"Member Login\",\n    description: \"Member login page.\"\n  )\n%>\n```\n\nYou can pass an object that implements the `#to_meta_tags` method and returns a Hash:\n\n```ruby\nclass Document \u003C ApplicationRecord\n  def to_meta_tags\n    {\n      title: title,\n      description: summary\n    }\n  end\nend\n\n@document = Document.first\nset_meta_tags @document\n```\n\nThe `title` method returns the title itself, so you can use it to show the title\nsomewhere on the page:\n\n```erb\n\u003Ch1>\u003C%= title \"Member Login\" %>\u003C\u002Fh1>\n```\n\nIf you want to set the title and display another text, use this:\n\n```erb\n\u003Ch1>\u003C%= title \"Member Login\", \"Here you can login to the site:\" %>\u003C\u002Fh1>\n```\n\n### Allowed options for `display_meta_tags` and `set_meta_tags` methods\n\nUse these options to customize the generated tags:\n\n| Option         | Description                                                                                                         |\n| -------------- | ------------------------------------------------------------------------------------------------------------------- |\n| `:site`        | Site title                                                                                                          |\n| `:title`       | Page title                                                                                                          |\n| `:description` | Page description                                                                                                    |\n| `:keywords`    | Legacy keywords meta tag for compatibility; ignored by Google Search and Bing web search                            |\n| `:charset`     | Page character set                                                                                                  |\n| `:prefix`      | Text between site name and separator                                                                                |\n| `:separator`   | Text used to separate the website name from the page title                                                          |\n| `:suffix`      | Text between separator and page title                                                                               |\n| `:lowercase`   | When true, the page name will be lowercase                                                                          |\n| `:reverse`     | When true, the page and site names will be reversed                                                                 |\n| `:noindex`     | Add noindex meta tag; when true, \"robots\" will be used; accepts a string with a robot name or an array of strings   |\n| `:index`       | Add index meta tag; when true, \"robots\" will be used; accepts a string with a robot name or an array of strings     |\n| `:nofollow`    | Add nofollow meta tag; when true, \"robots\" will be used; accepts a string with a robot name or an array of strings  |\n| `:follow`      | Add follow meta tag; when true, \"robots\" will be used; accepts a string with a robot name or an array of strings    |\n| `:noarchive`   | Add noarchive meta tag; when true, \"robots\" will be used; accepts a string with a robot name or an array of strings |\n| `:robots`      | Add custom directives to the `robots` meta tag (Hash)                                                               |\n| `:googlebot`   | Add custom directives to the `googlebot` meta tag (Hash)                                                            |\n| `:bingbot`     | Add custom directives to the `bingbot` meta tag (Hash)                                                              |\n| `:canonical`   | Add canonical link tag                                                                                              |\n| `:prev`        | Add legacy prev pagination link tag                                                                                 |\n| `:next`        | Add legacy next pagination link tag                                                                                 |\n| `:image_src`   | Add legacy image_src share hint                                                                                     |\n| `:og`          | Add Open Graph tags (Hash)                                                                                          |\n| `:twitter`     | Add Twitter tags (Hash)                                                                                             |\n| `:refresh`     | Refresh interval and optionally URL to redirect to                                                                  |\n\nAnd here are a few examples to give you ideas.\n\n```erb\n\u003C%= display_meta_tags separator: \"&mdash;\".html_safe %>\n\u003C%= display_meta_tags prefix: false, separator: \":\" %>\n\u003C%= display_meta_tags lowercase: true %>\n\u003C%= display_meta_tags reverse: true, prefix: false %>\n\u003C%= display_meta_tags og: { title: \"The Rock\", type: \"video.movie\" } %>\n\u003C%= display_meta_tags alternate: { \"zh-Hant\" => \"http:\u002F\u002Fexample.com.tw\u002Fbase\u002Furl\" } %>\n```\n\n### Allowed values\n\nYou can specify `:title` as a string or array:\n\n```ruby\nset_meta_tags title: [\"part1\", \"part2\"], site: \"site\"\n# site | part1 | part2\nset_meta_tags title: [\"part1\", \"part2\"], reverse: true, site: \"site\"\n# part2 | part1 | site\n```\n\nIf you still need the legacy `keywords` tag, values can be passed as a string of comma-separated values or as an array:\n\n```ruby\nset_meta_tags keywords: [\"tag1\", \"tag2\"]\n# tag1, tag2\n```\n\nThe description is a string (HTML will be stripped from the output string).\n\n### Mirrored values\n\nSometimes, it is desirable to mirror meta tag values down into namespaces. A common use case is when you want the open graph's `og:title` to be identical to the `title`.\n\nLet's say you have the following code in your application layout:\n\n```ruby\ndisplay_meta_tags og: {\n  title: :title,\n  site_name: :site\n}\n```\n\nThe value of `og[:title]` is a symbol, which refers to the value of the top-level `title` meta tag. In any view with the following code:\n\n```ruby\ntitle \"my great view\"\n```\n\nYou will get this open graph meta tag automatically:\n\n```html\n\u003Cmeta property=\"og:title\" content=\"my great view\">\u003C\u002Fmeta>\n```\n\n> [!NOTE]\n> The `title` does not include the site name. If you need to reference the exact value rendered in the `\u003Ctitle>` meta tag, use `:full_title`.\n\n### Using with Turbo\n\n[Turbo](https:\u002F\u002Fgithub.com\u002Fhotwired\u002Fturbo) is a simple solution for getting the performance benefits of a single-page application without the added complexity of a client-side JavaScript framework. MetaTags supports Turbo out of the box, so no configuration is necessary.\n\nIn order to update the page title, you can use the following trick. First, set the ID for the `\u003Ctitle>` HTML tag using MetaTags configuration in your initializer `config\u002Finitializers\u002Fmeta_tags.rb`:\n\n```ruby\nMetaTags.configure do |config|\n  config.title_tag_attributes = {id: \"page-title\"}\nend\n```\n\nNow in your turbo frame, you can update the title using a turbo stream:\n\n```html\n\u003Cturbo-frame ...>\n  \u003Cturbo-stream action=\"update\" target=\"page-title\">\n    \u003Ctemplate>My new title\u003C\u002Ftemplate>\n  \u003C\u002Fturbo-stream>\n\u003C\u002Fturbo-frame>\n```\n\n### Using with pjax\n\n[jQuery.pjax](https:\u002F\u002Fgithub.com\u002Fdefunkt\u002Fjquery-pjax) is a nice solution for navigation without a full-page reload. The main difference is that the layout file will not be rendered, so the page title will not change. To fix this, when using a page fragment, pjax will check the fragment DOM element for a `title` or `data-title` attribute and use any value it finds.\n\nMetaTags simplifies this with the `display_title` method, which returns the fully resolved page title (including site, prefix\u002Fsuffix, etc.). But in this case, you will have to set default parameters (e.g., `:site`) both in the layout file and in your views. To minimize code duplication, you can define a helper in `application_helper.rb`:\n\n```ruby\ndef default_meta_tags\n  {\n    title: \"Member Login\",\n    description: \"Member login page.\",\n    separator: \"&mdash;\".html_safe\n  }\nend\n```\n\nThen, in your layout file, use:\n\n```erb\n\u003C%= display_meta_tags(default_meta_tags) %>\n```\n\nAnd in your pjax templates:\n\n```erb\n\u003C!-- set title here so we can use it both in \"display_title\" and in \"title\" -->\n\u003C% title \"My Page title\" %>\n\u003C%= content_tag :div, data: { title: display_title(default_meta_tags) } do %>\n    \u003Ch1>\u003C%= title %>\u003C\u002Fh1>\n    \u003C!-- HTML goes here -->\n\u003C% end %>\n```\n\n## Search and Sharing Metadata\n\nThese 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.\n\n### Titles\n\nPage titles help browsers, social previews, and search engines understand the page. Use unique, descriptive titles that match the visible page content.\n\n```ruby\nset_meta_tags title: \"Member Login\"\n# \u003Ctitle>Member Login\u003C\u002Ftitle>\nset_meta_tags site: \"Site Title\", title: \"Member Login\"\n# \u003Ctitle>Site Title | Member Login\u003C\u002Ftitle>\nset_meta_tags site: \"Site Title\", title: \"Member Login\", reverse: true\n# \u003Ctitle>Member Login | Site Title\u003C\u002Ftitle>\n```\n\nGoogle does not publish a fixed title length. Keep titles concise and informative; search results may truncate them based on available width.\n\nFurther reading:\n\n- [Title Tag](https:\u002F\u002Fmoz.com\u002Flearn\u002Fseo\u002Ftitle-tag)\n- [Google Search Central: title links](https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\u002Fappearance\u002Ftitle-link)\n\n### Description\n\nDescription 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.\n\nBelow is an example of how to set a description tag using Ruby:\n\n```ruby\nset_meta_tags description: \"This is a sample description\"\n# \u003Cmeta name=\"description\" content=\"This is a sample description\">\n```\n\nGoogle 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.\n\nFurther reading:\n\n- [Meta Description](https:\u002F\u002Fmoz.com\u002Flearn\u002Fseo\u002Fmeta-description)\n- [How Long Should Your Meta Description Be? (2018 Edition)](https:\u002F\u002Fmoz.com\u002Fblog\u002Fhow-long-should-your-meta-description-be-2018)\n- [Google Search Central: control your snippets in search results](https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\u002Fappearance\u002Fsnippet)\n\n### Keywords\n\nThe `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.\n\n```ruby\nset_meta_tags keywords: %w[keyword1 keyword2 keyword3]\n# \u003Cmeta name=\"keywords\" content=\"keyword1, keyword2, keyword3\">\n```\n\n> [!NOTE]\n> 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.\n\nFurther reading:\n\n- [Google Search Central: meta tags Google supports](https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\u002Fcrawling-indexing\u002Fspecial-tags)\n\n### Noindex\n\nBy using the noindex meta tag, you can signal to search engines not to include specific pages in their indexes.\n\n```ruby\nset_meta_tags noindex: true\n# \u003Cmeta name=\"robots\" content=\"noindex\">\nset_meta_tags noindex: \"googlebot\"\n# \u003Cmeta name=\"googlebot\" content=\"noindex\">\n```\n\nThis is useful for pages like login, password reset, cart, account settings, or internal search results.\n\nFurther reading:\n\n- [Blocking Google](http:\u002F\u002Fwww.google.com\u002Fsupport\u002Fwebmasters\u002Fbin\u002Fanswer.py?hl=en&answer=93708)\n- [Using meta tags to block access to your site](http:\u002F\u002Fwww.google.com\u002Fsupport\u002Fwebmasters\u002Fbin\u002Fanswer.py?hl=en&answer=93710)\n- [Google Search Central: robots meta tag and X-Robots-Tag](https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\u002Fcrawling-indexing\u002Frobots-meta-tag)\n\n### Index\n\nIn most cases, you do not need to emit `index` explicitly because it is already the default for crawlable pages.\n\n```ruby\nset_meta_tags index: true\n# \u003Cmeta name=\"robots\" content=\"index\">\n```\n\n### Nofollow\n\nNofollow 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.\n\n```ruby\nset_meta_tags nofollow: true\n# \u003Cmeta name=\"robots\" content=\"nofollow\">\nset_meta_tags nofollow: \"googlebot\"\n# \u003Cmeta name=\"googlebot\" content=\"nofollow\">\n```\n\nFurther reading:\n\n- [About rel=\"nofollow\"](http:\u002F\u002Fwww.google.com\u002Fsupport\u002Fwebmasters\u002Fbin\u002Fanswer.py?answer=96569)\n- [Meta tags](http:\u002F\u002Fwww.google.com\u002Fsupport\u002Fwebmasters\u002Fbin\u002Fanswer.py?hl=en&answer=79812)\n- [Google Search Central: robots meta tag and X-Robots-Tag](https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\u002Fcrawling-indexing\u002Frobots-meta-tag)\n\n### Follow\n\nYou 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.\n\n```ruby\nset_meta_tags noindex: true, follow: true\n# \u003Cmeta name=\"robots\" content=\"noindex, follow\">\n```\n\nThis 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.\n\n### Robots\n\nUse the `robots`, `googlebot`, and `bingbot` hashes when you need directives beyond `index`, `noindex`, `follow`, `nofollow`, and `noarchive`.\n\nThis is useful for directives such as `max-snippet`, `max-video-preview`, and `unavailable_after`.\n\n```ruby\nset_meta_tags robots: {\n  \"max-snippet\" => -1,\n  \"max-video-preview\" => -1\n}\n# \u003Cmeta name=\"robots\" content=\"max-snippet:-1, max-video-preview:-1\">\n\nset_meta_tags googlebot: {\n  unavailable_after: \"2026-12-31\"\n}\n# \u003Cmeta name=\"googlebot\" content=\"unavailable_after:2026-12-31\">\n\nset_meta_tags bingbot: {\n  \"max-image-preview\" => \"large\"\n}\n# \u003Cmeta name=\"bingbot\" content=\"max-image-preview:large\">\n```\n\nThese hashes are merged with the existing robots helpers, so `noindex`, `nofollow`, and similar directives still render first for the same meta tag.\n\nFurther reading:\n\n- [Google Search Central: robots meta tag and X-Robots-Tag](https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\u002Fcrawling-indexing\u002Frobots-meta-tag)\n- [Bing Webmaster Guidelines: robots meta tag support](https:\u002F\u002Fwww.bing.com\u002Fwebmasters\u002Fhelp\u002Fwhich-robots-metatags-does-bing-support-5198d240)\n\n### Canonical URL\n\nCanonical link elements help search engines consolidate duplicate or near-duplicate URLs under one preferred URL. They are a signal, not a guarantee.\n\n> [!NOTE]\n> 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`.\n\n```ruby\nset_meta_tags canonical: \"http:\u002F\u002Fyoursite.com\u002Fcanonical\u002Furl\"\n# \u003Clink rel=\"canonical\" href=\"http:\u002F\u002Fyoursite.com\u002Fcanonical\u002Furl\">\n```\n\nFurther reading:\n\n- [About rel=\"canonical\"](http:\u002F\u002Fwww.google.com\u002Fsupport\u002Fwebmasters\u002Fbin\u002Fanswer.py?hl=en&answer=139394)\n- [Canonicalization](http:\u002F\u002Fwww.google.com\u002Fsupport\u002Fwebmasters\u002Fbin\u002Fanswer.py?hl=en&answer=139066)\n- [Google Search Central: canonicalization and duplicate URLs](https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\u002Fcrawling-indexing\u002Fconsolidate-duplicate-urls)\n\n### Icon\n\nA 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.\n\n```ruby\nset_meta_tags icon: \"\u002Ffavicon.ico\"\n# \u003Clink rel=\"icon\" href=\"\u002Ffavicon.ico\" type=\"image\u002Fx-icon\">\nset_meta_tags icon: \"\u002Ffavicon.png\", type: \"image\u002Fpng\"\n# \u003Clink rel=\"icon\" href=\"\u002Ffavicon.png\" type=\"image\u002Fpng\">\nset_meta_tags icon: [\n  {href: \"\u002Fimages\u002Ficons\u002Ficon_96.png\", sizes: \"32x32 96x96\", type: \"image\u002Fpng\"},\n  {href: \"\u002Fimages\u002Ficons\u002Ficon_itouch_precomp_32.png\", rel: \"apple-touch-icon-precomposed\", sizes: \"32x32\", type: \"image\u002Fpng\"}\n]\n# \u003Clink rel=\"icon\" href=\"\u002Fimages\u002Ficons\u002Ficon_96.png\" type=\"image\u002Fpng\" sizes=\"32x32 96x96\">\n# \u003Clink rel=\"apple-touch-icon-precomposed\" href=\"\u002Fimages\u002Ficons\u002Ficon_itouch_precomp_32.png\" type=\"image\u002Fpng\" sizes=\"32x32\">\n```\n\nFurther reading:\n\n- [Favicon](https:\u002F\u002Fwww.wikiwand.com\u002Fen\u002FFavicon)\n- [Touch Icons](https:\u002F\u002Fmathiasbynens.be\u002Fnotes\u002Ftouch-icons)\n\n### Multi-regional and multilingual URLs, RSS and mobile links\n\nAlternate link elements tell a search engine when there is content that's translated or targeted to users in a certain region.\n\n```ruby\nset_meta_tags alternate: {\"fr\" => \"http:\u002F\u002Fyoursite.fr\u002Falternate\u002Furl\"}\n# \u003Clink rel=\"alternate\" href=\"http:\u002F\u002Fyoursite.fr\u002Falternate\u002Furl\" hreflang=\"fr\">\n\nset_meta_tags alternate: {\"fr\" => \"http:\u002F\u002Fyoursite.fr\u002Falternate\u002Furl\",\n                          \"de\" => \"http:\u002F\u002Fyoursite.de\u002Falternate\u002Furl\"}\n# \u003Clink rel=\"alternate\" href=\"http:\u002F\u002Fyoursite.fr\u002Falternate\u002Furl\" hreflang=\"fr\">\n# \u003Clink rel=\"alternate\" href=\"http:\u002F\u002Fyoursite.de\u002Falternate\u002Furl\" hreflang=\"de\">\n```\n\nIf you need more than just multi-lingual links, you can use an alternative syntax:\n\n```ruby\nset_meta_tags alternate: [\n  {href: \"http:\u002F\u002Fexample.fr\u002Fbase\u002Furl\", hreflang: \"fr\"},\n  {href: \"http:\u002F\u002Fexample.com\u002Ffeed.rss\", type: \"application\u002Frss+xml\", title: \"RSS\"},\n  {href: \"http:\u002F\u002Fm.example.com\u002Fpage-1\", media: \"only screen and (max-width: 640px)\"}\n]\n```\n\nFurther reading:\n\n- [Multi-regional and multilingual sites](https:\u002F\u002Fsupport.google.com\u002Fwebmasters\u002Fanswer\u002F182192)\n- [About rel=\"alternate\" hreflang=\"x\"](http:\u002F\u002Fwww.google.com\u002Fsupport\u002Fwebmasters\u002Fbin\u002Fanswer.py?hl=en&answer=189077)\n- [Separate URLs](https:\u002F\u002Fdevelopers.google.com\u002Fwebmasters\u002Fmobile-sites\u002Fmobile-seo\u002Fconfigurations\u002Fseparate-urls#annotation-in-the-html)\n\n### Pagination links\n\nPrevious 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.\n\n```ruby\nset_meta_tags prev: \"http:\u002F\u002Fyoursite.com\u002Furl?page=1\"\n# \u003Clink rel=\"prev\" href=\"http:\u002F\u002Fyoursite.com\u002Furl?page=1\">\nset_meta_tags next: \"http:\u002F\u002Fyoursite.com\u002Furl?page=3\"\n# \u003Clink rel=\"next\" href=\"http:\u002F\u002Fyoursite.com\u002Furl?page=3\">\n```\n\nFurther reading:\n\n- [Pagination](http:\u002F\u002Fsupport.google.com\u002Fwebmasters\u002Fbin\u002Fanswer.py?hl=en&answer=1663744)\n- [Pagination with rel=\"next\" and rel=\"prev\"](http:\u002F\u002Fgooglewebmastercentral.blogspot.ca\u002F2011\u002F09\u002Fpagination-with-relnext-and-relprev.html)\n- [Google Search Central: pagination, incremental page loading, and infinite scroll](https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\u002Fspecialty\u002Fecommerce\u002Fpagination-and-incremental-page-loading)\n\n### image_src links\n\n`image_src` is a legacy share hint. Modern social sharing generally relies on Open Graph images and platform-specific card tags instead.\n\n```ruby\nset_meta_tags image_src: \"http:\u002F\u002Fyoursite.com\u002Ficons\u002Ficon_32.png\"\n# \u003Clink rel=\"image_src\" href=\"http:\u002F\u002Fyoursite.com\u002Ficons\u002Ficon_32.png\">\n```\n\n### amphtml links\n\nIf 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.\n\n```ruby\nset_meta_tags amphtml: url_for(format: :amp, only_path: false)\n# \u003Clink rel=\"amphtml\" href=\"https:\u002F\u002Fwww.example.com\u002Fdocument.amp\">\n```\n\nTo link back to the normal version, use the `canonical` tag.\n\n- [AMP documentation](https:\u002F\u002Famp.dev\u002Fdocumentation\u002F)\n\n### Manifest links\n\nBy including the `rel=\"manifest\"` attribute in the `\u003Clink>` 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.\n\n```ruby\nset_meta_tags manifest: \"manifest.json\"\n# \u003Clink rel=\"manifest\" href=\"manifest.json\">\n```\n\n- [What is manifest?](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FManifest)\n\n### Refresh interval and redirect URL\n\nMeta 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.\n\n```ruby\nset_meta_tags refresh: 5\n# \u003Cmeta content=\"5\" http-equiv=\"refresh\">\nset_meta_tags refresh: \"5;url=http:\u002F\u002Fexample.com\"\n# \u003Cmeta content=\"5;url=http:\u002F\u002Fexample.com\" http-equiv=\"refresh\">\n```\n\nFurther reading:\n\n- [Meta refresh](http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FMeta_refresh)\n- [What is the Meta Refresh Tag](http:\u002F\u002Fwebdesign.about.com\u002Fod\u002Fmetataglibraries\u002Fa\u002Faa080300a.htm)\n\n### Open Search\n\nOpen Search is a link element used to describe a search engine in a standard and accessible format.\n\n```ruby\nset_meta_tags open_search: {\n  title: \"Open Search\",\n  href: \"\u002Fopensearch.xml\"\n}\n# \u003Clink href=\"\u002Fopensearch.xml\" rel=\"search\" title=\"Open Search\" type=\"application\u002Fopensearchdescription+xml\">\n```\n\nFurther reading:\n\n- [OpenSearch specs](http:\u002F\u002Fwww.opensearch.org\u002FSpecifications\u002FOpenSearch\u002F1.1)\n- [OpenSearch wiki](http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FOpenSearch)\n\n### Hashes\n\nAny namespace can be created by simply passing a symbol name and a Hash. For example:\n\n```ruby\nset_meta_tags foo: {\n  bar: \"lorem\",\n  baz: {\n    qux: \"ipsum\"\n  }\n}\n# \u003Cmeta property=\"foo:bar\" content=\"lorem\">\n# \u003Cmeta property=\"foo:baz:qux\" content=\"ipsum\">\n```\n\n### Arrays\n\nRepeated meta tags can be easily created by using an Array within a Hash. For example:\n\n```ruby\nset_meta_tags og: {\n  image: [\"http:\u002F\u002Fexample.com\u002Frock.jpg\", \"http:\u002F\u002Fexample.com\u002Frock2.jpg\"]\n}\n# \u003Cmeta property=\"og:image\" content=\"http:\u002F\u002Fexample.com\u002Frock.jpg\">\n# \u003Cmeta property=\"og:image\" content=\"http:\u002F\u002Fexample.com\u002Frock2.jpg\">\n```\n\n### Open Graph\n\nTo turn your web pages into graph objects, you'll need to add Open Graph protocol `\u003Cmeta>` 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:\n\n```ruby\nset_meta_tags og: {\n  title: \"The Rock\",\n  type: \"video.movie\",\n  url: \"http:\u002F\u002Fwww.imdb.com\u002Ftitle\u002Ftt0117500\u002F\",\n  image: \"http:\u002F\u002Fia.media-imdb.com\u002Frock.jpg\",\n  video: {\n    director: \"http:\u002F\u002Fwww.imdb.com\u002Fname\u002Fnm0000881\u002F\",\n    writer: [\"http:\u002F\u002Fwww.imdb.com\u002Fname\u002Fnm0918711\u002F\", \"http:\u002F\u002Fwww.imdb.com\u002Fname\u002Fnm0177018\u002F\"]\n  }\n}\n# \u003Cmeta property=\"og:title\" content=\"The Rock\">\n# \u003Cmeta property=\"og:type\" content=\"video.movie\">\n# \u003Cmeta property=\"og:url\" content=\"http:\u002F\u002Fwww.imdb.com\u002Ftitle\u002Ftt0117500\u002F\">\n# \u003Cmeta property=\"og:image\" content=\"http:\u002F\u002Fia.media-imdb.com\u002Frock.jpg\">\n# \u003Cmeta property=\"og:video:director\" content=\"http:\u002F\u002Fwww.imdb.com\u002Fname\u002Fnm0000881\u002F\">\n# \u003Cmeta property=\"og:video:writer\" content=\"http:\u002F\u002Fwww.imdb.com\u002Fname\u002Fnm0918711\u002F\">\n# \u003Cmeta property=\"og:video:writer\" content=\"http:\u002F\u002Fwww.imdb.com\u002Fname\u002Fnm0177018\u002F\">\n```\n\nMultiple images declared as an **array** (look at the `_` character):\n\n```ruby\nset_meta_tags og: {\n  title: \"Two structured image properties\",\n  type: \"website\",\n  url: \"view-source:http:\u002F\u002Fexamples.opengraphprotocol.us\u002Fimage-array.html\",\n  image: [\n    {\n      _: \"http:\u002F\u002Fexamples.opengraphprotocol.us\u002Fmedia\u002Fimages\u002F75.png\",\n      width: 75,\n      height: 75\n    },\n    {\n      _: \"http:\u002F\u002Fexamples.opengraphprotocol.us\u002Fmedia\u002Fimages\u002F50.png\",\n      width: 50,\n      height: 50\n    }\n  ]\n}\n# \u003Cmeta property=\"og:title\" content=\"Two structured image properties\">\n# \u003Cmeta property=\"og:type\" content=\"website\">\n# \u003Cmeta property=\"og:url\" content=\"http:\u002F\u002Fexamples.opengraphprotocol.us\u002Fimage-array.html\">\n# \u003Cmeta property=\"og:image\" content=\"http:\u002F\u002Fexamples.opengraphprotocol.us\u002Fmedia\u002Fimages\u002F75.png\">\n# \u003Cmeta property=\"og:image:width\" content=\"75\">\n# \u003Cmeta property=\"og:image:height\" content=\"75\">\n# \u003Cmeta property=\"og:image\" content=\"http:\u002F\u002Fexamples.opengraphprotocol.us\u002Fmedia\u002Fimages\u002F50.png\">\n# \u003Cmeta property=\"og:image:width\" content=\"50\">\n# \u003Cmeta property=\"og:image:height\" content=\"50\">\n```\n\nArticle meta tags are supported too:\n\n```ruby\nset_meta_tags article: {\n  published_time: \"2013-09-17T05:59:00+01:00\",\n  modified_time: \"2013-09-16T19:08:47+01:00\",\n  section: \"Article Section\",\n  tag: \"Article Tag\"\n}\n# \u003Cmeta property=\"article:published_time\" content=\"2013-09-17T05:59:00+01:00\">\n# \u003Cmeta property=\"article:modified_time\" content=\"2013-09-16T19:08:47+01:00\">\n# \u003Cmeta property=\"article:section\" content=\"Article Section\">\n# \u003Cmeta property=\"article:tag\" content=\"Article Tag\">\n```\n\nFurther reading:\n\n- [Open Graph protocol](http:\u002F\u002Fdevelopers.facebook.com\u002Fdocs\u002Fopengraph\u002F)\n- [Open Graph protocol](https:\u002F\u002Fogp.me\u002F)\n- [Must-Have Social Meta Tags for Twitter, Google+, Facebook and More](https:\u002F\u002Fmoz.com\u002Fblog\u002Fmeta-data-templates-123)\n- [X for Websites documentation](https:\u002F\u002Fdeveloper.x.com\u002Fen\u002Fdocs\u002Fx-for-websites)\n\n### Twitter Cards\n\nX cards let links shared on X show richer previews. The metadata namespace is still `twitter:*`. Here is a simple summary card example:\n\n```ruby\nset_meta_tags twitter: {\n  card: \"summary\",\n  site: \"@username\"\n}\n# \u003Cmeta name=\"twitter:card\" content=\"summary\">\n# \u003Cmeta name=\"twitter:site\" content=\"@username\">\n```\n\nIf 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.\n\nWhen 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:\n\n```ruby\nset_meta_tags twitter: {\n  card: \"summary_large_image\",\n  image: {\n    _: \"http:\u002F\u002Fexample.com\u002F1.png\",\n    width: 100,\n    height: 100,\n    alt: \"Cover image\"\n  }\n}\n# \u003Cmeta name=\"twitter:card\" content=\"summary_large_image\">\n# \u003Cmeta name=\"twitter:image\" content=\"http:\u002F\u002Fexample.com\u002F1.png\">\n# \u003Cmeta name=\"twitter:image:width\" content=\"100\">\n# \u003Cmeta name=\"twitter:image:height\" content=\"100\">\n# \u003Cmeta name=\"twitter:image:alt\" content=\"Cover image\">\n```\n\nA special parameter `itemprop` can be used on an \"anonymous\" tag \"\\_\" to generate the \"itemprop\" HTML attribute:\n\n```ruby\nset_meta_tags twitter: {\n  card: \"summary_large_image\",\n  image: {\n    _: \"http:\u002F\u002Fexample.com\u002F1.png\",\n    width: 100,\n    height: 100,\n    alt: \"Cover image\",\n    itemprop: \"image\"\n  }\n}\n# \u003Cmeta name=\"twitter:card\" content=\"summary_large_image\">\n# \u003Cmeta name=\"twitter:image\" content=\"http:\u002F\u002Fexample.com\u002F1.png\" itemprop=\"image\">\n# \u003Cmeta name=\"twitter:image:width\" content=\"100\">\n# \u003Cmeta name=\"twitter:image:height\" content=\"100\">\n# \u003Cmeta name=\"twitter:image:alt\" content=\"Cover image\">\n```\n\nFurther reading:\n\n- [X for Websites documentation](https:\u002F\u002Fdeveloper.x.com\u002Fen\u002Fdocs\u002Fx-for-websites)\n\n### App Links\n\nApp Links is an open cross-platform solution for deep linking to content in your mobile app. Here's an example of iOS app integration:\n\n```ruby\nset_meta_tags al: {\n  ios: {\n    url: \"example:\u002F\u002Fapplinks\",\n    app_store_id: 12345,\n    app_name: \"Example App\"\n  }\n}\n# \u003Cmeta property=\"al:ios:url\" content=\"example:\u002F\u002Fapplinks\">\n# \u003Cmeta property=\"al:ios:app_store_id\" content=\"12345\">\n# \u003Cmeta property=\"al:ios:app_name\" content=\"Example App\">\n```\n\nFurther reading:\n\n- [App Links Documentation](https:\u002F\u002Fdevelopers.facebook.com\u002Fdocs\u002Fapplinks)\n\n### Custom meta tags\n\nStarting from version 1.3.1, you can specify arbitrary meta tags, and they will be rendered on the page, even if the meta-tags gem does not know about them.\n\nExample:\n\n```ruby\nset_meta_tags author: \"Dmytro Shteflyuk\"\n# \u003Cmeta name=\"author\" content=\"Dmytro Shteflyuk\">\n```\n\nYou can also specify the value as an Array, and the values will be displayed as a list of `meta` tags:\n\n```ruby\nset_meta_tags author: [\"Dmytro Shteflyuk\", \"John Doe\"]\n# \u003Cmeta name=\"author\" content=\"Dmytro Shteflyuk\">\n# \u003Cmeta name=\"author\" content=\"John Doe\">\n```\n\n## Maintainers\n\n[Dmytro Shteflyuk](https:\u002F\u002Fgithub.com\u002Fkpumuk), [https:\u002F\u002Fdmytro.sh](https:\u002F\u002Fdmytro.sh)\n","MetaTags 是一个为 Ruby on Rails 应用程序提供搜索引擎优化（SEO）的库。它能够帮助开发者轻松地在 HTML 头部添加包括标题、描述、canonical 链接、robots 指令、Open Graph 标签、Twitter 卡片等在内的元数据，从而提升网站在搜索引擎中的表现和社交媒体上的分享效果。该项目支持 Ruby on Rails 6.1 及以上版本，并且遵循 MIT 许可证开放源代码。MetaTags 特别适用于需要增强 SEO 性能的 Web 开发项目中，通过提供一系列预设配置与自定义选项来满足不同应用场景的需求，但不涉及结构化数据生成或 sitemap 创建等功能。",2,"2026-06-11 03:15:02","top_language"]