From b6b0218e1db12ee4994736dbfd98269714b66637 Mon Sep 17 00:00:00 2001 From: evazion Date: Fri, 3 Jul 2020 16:04:13 -0500 Subject: [PATCH] seo: update JSON-LD site metadata. * Add the Danbooru logo and social media links to the Organization data. This is to make Danbooru eligible for Google's knowledge panel ([1], [2]). * Only include this metadata on the frontpage as per Google's recommendations ([3]). [1]: https://support.google.com/knowledgepanel/answer/9163198 [2], https://developers.google.com/search/docs/data-types/logo [3]: https://developers.google.com/search/docs/data-types/sitelinks-searchbox --- app/helpers/seo_helper.rb | 56 ++++++++++++++++++ app/views/layouts/default.html.erb | 40 ++----------- .../partials/index/_seo_meta_tags.html.erb | 2 +- config/danbooru_default_config.rb | 5 ++ public/images/danbooru-logo-500x500.png | Bin 0 -> 29388 bytes 5 files changed, 67 insertions(+), 36 deletions(-) create mode 100644 app/helpers/seo_helper.rb create mode 100644 public/images/danbooru-logo-500x500.png diff --git a/app/helpers/seo_helper.rb b/app/helpers/seo_helper.rb new file mode 100644 index 000000000..60330ada5 --- /dev/null +++ b/app/helpers/seo_helper.rb @@ -0,0 +1,56 @@ +# https://yoast.com/structured-data-schema-ultimate-guide/ +# https://technicalseo.com/tools/schema-markup-generator/ +# https://developers.google.com/search/docs/data-types/sitelinks-searchbox +# https://developers.google.com/search/docs/data-types/logo +# https://search.google.com/structured-data/testing-tool/u/0/ +# https://search.google.com/test/rich-results +# https://schema.org/Organization +# https://schema.org/WebSite + +module SeoHelper + def site_description + "#{Danbooru.config.canonical_app_name} is the original anime image booru. Search millions of anime pictures categorized by thousands of tags." + end + + def json_ld_website_data + urls = [ + Danbooru.config.twitter_url, + Danbooru.config.discord_server_url, + Danbooru.config.source_code_url, + "https://en.wikipedia.org/wiki/Danbooru" + ].compact + + json_ld_tag({ + "@context": "https://schema.org", + "@graph": [ + { + "@type": "Organization", + "@id": root_url(anchor: "organization", host: Danbooru.config.hostname), + url: root_url(host: Danbooru.config.hostname), + name: Danbooru.config.app_name, + logo: "#{root_url(host: Danbooru.config.hostname)}images/danbooru-logo-500x500.png", + sameAs: urls + }, + { + "@type": "WebSite", + "@id": root_url(anchor: "website", host: Danbooru.config.hostname), + "url": root_url(host: Danbooru.config.hostname), + "name": Danbooru.config.app_name, + "description": site_description, + "publisher": { + "@id": root_url(anchor: "organization", host: Danbooru.config.hostname), + }, + "potentialAction": [{ + "@type": "SearchAction", + "target": "#{posts_url(host: Danbooru.config.hostname)}?tags={search_term_string}", + "query-input": "required name=search_term_string" + }] + } + ] + }) + end + + def json_ld_tag(data) + tag.script(data.to_json.html_safe, type: "application/ld+json") + end +end diff --git a/app/views/layouts/default.html.erb b/app/views/layouts/default.html.erb index 2c1f65349..6dcb21581 100644 --- a/app/views/layouts/default.html.erb +++ b/app/views/layouts/default.html.erb @@ -19,42 +19,12 @@ <% if CurrentUser.user.custom_style.present? && params.fetch(:css, "true").truthy? %> <%= stylesheet_link_tag custom_style_users_path(md5: Digest::MD5.hexdigest(CurrentUser.user.custom_style)), media: "screen" %> <% end %> - <% if Danbooru.config.twitter_username.present? %> - - <% end %> - - - <%= tag.meta name: "description", content: meta_description %> + <% if current_page?(root_url) %> + <%= json_ld_website_data %> + <% end %> + + <%= tag.meta name: "description", content: meta_description %> <%= tag.meta property: "og:type", content: "website" %> <%= tag.meta property: "og:site_name", content: Danbooru.config.app_name %> <%= tag.meta property: "og:title", content: page_title %> diff --git a/app/views/posts/partials/index/_seo_meta_tags.html.erb b/app/views/posts/partials/index/_seo_meta_tags.html.erb index 1c58f8d5a..cedb48987 100644 --- a/app/views/posts/partials/index/_seo_meta_tags.html.erb +++ b/app/views/posts/partials/index/_seo_meta_tags.html.erb @@ -1,6 +1,6 @@ <% if @post_set.query.is_empty_search? %> <% page_title("#{Danbooru.config.app_name}: Anime Image Board", suffix: nil) %> - <% meta_description("#{Danbooru.config.canonical_app_name} is the original anime image 'booru. Find over 3.75 million anime pictures categorized by over 100 million tags.") %> + <% meta_description site_description %> <% atom_feed_tag "Posts", posts_url(format: :atom) %> <% else %> diff --git a/config/danbooru_default_config.rb b/config/danbooru_default_config.rb index f9570949c..439673809 100644 --- a/config/danbooru_default_config.rb +++ b/config/danbooru_default_config.rb @@ -355,6 +355,11 @@ module Danbooru nil end + def twitter_url + return nil unless Danbooru.config.twitter_username.present? + "https://twitter.com/#{Danbooru.config.twitter_username}" + end + # include essential tags in image urls (requires nginx/apache rewrites) def enable_seo_post_urls false diff --git a/public/images/danbooru-logo-500x500.png b/public/images/danbooru-logo-500x500.png new file mode 100644 index 0000000000000000000000000000000000000000..5e652ad8235793d9136a11408df6981115b8ab9e GIT binary patch literal 29388 zcmeAS@N?(olHy`uVBq!ia0y~yVEh8Y9Bd2>45zQ%?_yw3VDNNt45^s&W-t35ne@u{ z|8Eyn1zNhthP~gG<2~(ZTkgZWn-ak}2OOBpTkcr26cq2g1EZr+`Fv%Ej;nf3W- zMkfx%7J=bLIC@U8W^NHka?A6YEZyU3^gT$wv?=xOyHZ7?X(`|5EeVXA_rg8RB)MF| zNsFCpu0T-GGL6XPliQXAAK0;UVpP_|s;`GL0$)!qTB*BzP2kGVr6qau)uz5G{%yMA z$_qv5Sgo(CuPhJR?&Yji`fS>#n+;yaL#!5F`gpZ`!S{;&ishclJC{zJ@}iypYtt_E z)OIKJmXvzNvjOZw}5o{mx8|&E?DCohFy;b2{p_cBwU^OZ{k*lX}aJWozY5zVvO|@p^)2#oOiQonPmkHV9sOJ}@&c&(e6i@6rIB zna{1)b;NbO|Gr|2^U~b?72MVPKbTZa(7hyYajV_Y?W2m0Mu}60^5iK8o^O@-dL_vH z?uW+I8GqPU7qA^WqU+gpKKs;+vrbc-pZUG_zPQ)rW4`CFhqG^d=GT`#`t?)Y`+age za%n97HBJkKop_=`_Ux_M6nK8E^bFHDTlUHO3lyKN{(4kPHzd<+6Ys@EPO2yGtaIHf za#TJjbGBFXlsn(=Ze>-!y36Hb?QLs=nl<}B^sBfmxWKtGN$Rr4nt5p)ds0)SqxNk) zmoZ@*LuBRYAeOl3b2e-XE~Vy``>gD~zw%Pp)UukNl`_>C{U77Lzjik)NNTufUD)QN zzNBk~C)4zER#*RKADScP^Jn>L1OK)9&SqTmTTkiPm3xb%=G}FRIxQcTx!ddZzbBb* zYCj6}t^Vq_RmRGa!|9mgLSdoebu+tNj1s@Ro_8UpxwAYbe~X!TrM{~fSH500+hKJ+ zqwUtqM9$_1zC7!1-`5;%&9ifUO^v==Rl6fctDlF=&M?nCdZ{iC-=yqc`TJX^?*}-#pRAVTnma+F@UG346&f|S zwy!^MrL(kc&-tKC%T0?{9i5vsVP~nP@3SS*cb?srKlbe$qfE$a_xfFDB@Xt5NQzh~ z3c9;KK08^ur!jh2?bF-{i>-p`%F*h2t}m|^^@cA#v-bT-jk4JxRezKD6aGKY;Jdq3 za!uxXrBzRp)K$V_Y}tE_XB+yiJ@@BMl+KLnSy$S-kDNB;ind&M=D2?9g;~0X7gspD zzO80+-|+w3SvPYFp<;~^C#6H8=?l^xx+Gg%y}5mUGpn|mwChWyLdpL&q4(}g8xaLmadbTOjV_lB zYcDVD)mioT@Zm#Rn_3S4F7vjHj#~J3kyi2N!l&h@QjBKze@i?)eg1L1tu}5OkMn~J zdAvySK&x?2UfSmSI|V*p&7Sx}XzH_rw?!5Px}2|{cWQ0_>?qNn&t0yE@`f$Ex!1hu z
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