Skip to content

Commit d65cc52

Browse files
committed
Add canonical link tag helper
1 parent 1e32636 commit d65cc52

File tree

4 files changed

+58
-0
lines changed

4 files changed

+58
-0
lines changed

app/helpers/better_together/application_helper.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,25 @@ def open_graph_meta_tags # rubocop:todo Metrics/AbcSize, Metrics/MethodLength, M
138138
# rubocop:enable Metrics/MethodLength
139139
# rubocop:enable Metrics/PerceivedComplexity
140140

141+
# Generates a canonical link tag for the current request.
142+
# Defaults to request.original_url but can be overridden by setting
143+
# `content_for(:canonical_url)` in views. When provided a relative path,
144+
# the host and locale are ensured by prefixing with `base_url_with_locale`.
145+
def canonical_link_tag
146+
canonical_url = if content_for?(:canonical_url)
147+
content_for(:canonical_url)
148+
else
149+
request.original_url
150+
end
151+
152+
unless canonical_url.starts_with?('http://', 'https://')
153+
path = canonical_url.sub(%r{^/#{I18n.locale}}, '')
154+
canonical_url = "#{base_url_with_locale}#{path}"
155+
end
156+
157+
tag.link(rel: 'canonical', href: canonical_url)
158+
end
159+
141160
# Retrieves the setup wizard for hosts or raises an error if not found.
142161
# This is crucial for initial setup processes and should be pre-configured.
143162
def host_setup_wizard

app/views/layouts/better_together/application.html.erb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
<title><%= (yield(:page_title) + ' | ') if content_for?(:page_title) %><%= host_platform.name %></title>
1212
<%= open_graph_meta_tags %>
1313
<%= seo_meta_tags %>
14+
<%= canonical_link_tag %>
1415
<meta name="color-scheme" content="light dark">
1516
<meta name="viewport" content="width=device-width, initial-scale=1.0">
1617
<%= csrf_meta_tags %>

app/views/layouts/better_together/turbo_native.html.erb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
<title><%= (yield(:page_title) + ' | ') if content_for?(:page_title) %><%= host_platform.name %></title>
1212
<%= open_graph_meta_tags %>
1313
<%= seo_meta_tags %>
14+
<%= canonical_link_tag %>
1415
<meta name="color-scheme" content="light dark">
1516
<meta name="viewport" content="width=device-width, initial-scale=1.0">
1617
<%= csrf_meta_tags %>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# frozen_string_literal: true
2+
3+
require 'rails_helper'
4+
5+
module BetterTogether
6+
RSpec.describe ApplicationHelper, type: :helper do
7+
describe '#canonical_link_tag' do
8+
before do
9+
allow(helper).to receive(:base_url_with_locale).and_return('https://example.com/en')
10+
end
11+
12+
context 'when no canonical_url is provided' do
13+
it 'defaults to request.original_url' do
14+
allow(helper.request).to receive(:original_url).and_return('https://example.com/en/posts')
15+
result = helper.canonical_link_tag
16+
expect(result).to include('href="https://example.com/en/posts"')
17+
end
18+
end
19+
20+
context 'when canonical_url is a relative path with locale' do
21+
it 'prefixes base_url_with_locale and removes duplicate locale' do
22+
helper.content_for(:canonical_url, '/en/custom')
23+
result = helper.canonical_link_tag
24+
expect(result).to include('href="https://example.com/en/custom"')
25+
end
26+
end
27+
28+
context 'when canonical_url is a full URL' do
29+
it 'uses the provided URL' do
30+
helper.content_for(:canonical_url, 'https://external.test/path')
31+
result = helper.canonical_link_tag
32+
expect(result).to include('href="https://external.test/path"')
33+
end
34+
end
35+
end
36+
end
37+
end

0 commit comments

Comments
 (0)