Class: BetterSeo::Validators::SeoRecommendations

Inherits:
Object
  • Object
show all
Defined in:
lib/better_seo/validators/seo_recommendations.rb

Instance Method Summary collapse

Instance Method Details

#format_recommendations(recommendations) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/better_seo/validators/seo_recommendations.rb', line 139

def format_recommendations(recommendations)
  return "# SEO Recommendations\n\nNo recommendations - your SEO is optimal! ✓" if recommendations.empty?

  output = []
  output << "# SEO Recommendations\n"

  # Group by priority
  grouped = recommendations.group_by { |r| r[:priority] }

  %i[high medium low].each do |priority|
    next unless grouped[priority]

    output << "## #{priority.to_s.capitalize} Priority\n"

    grouped[priority].each do |rec|
      output << "### #{rec[:category]}"
      output << "**Action:** #{rec[:action]}\n"
      output << "**Details:** #{rec[:details]}\n" if rec[:details]
      output << ""
    end
  end

  output.join("\n")
end

#generate_recommendations(validation_result) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
# File 'lib/better_seo/validators/seo_recommendations.rb', line 6

def generate_recommendations(validation_result)
  recommendations = []

  recommendations += recommend_title_improvements(validation_result[:title])
  recommendations += recommend_description_improvements(validation_result[:description])
  recommendations += recommend_heading_improvements(validation_result[:headings])
  recommendations += recommend_image_improvements(validation_result[:images])

  # Sort by priority: high, medium, low
  priority_order = { high: 0, medium: 1, low: 2 }
  recommendations.sort_by { |r| priority_order[r[:priority]] }
end

#recommend_description_improvements(desc_result) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/better_seo/validators/seo_recommendations.rb', line 53

def recommend_description_improvements(desc_result)
  return [] if desc_result[:valid]

  recommendations = []
  length = desc_result[:length]

  if length.zero?
    recommendations << {
      category: "Meta Description",
      priority: :high,
      action: "Add a meta description",
      details: "Meta descriptions help search engines understand your content. Aim for 120-160 characters."
    }
  elsif length < 120
    needed = 120 - length
    recommendations << {
      category: "Meta Description",
      priority: :medium,
      action: "Add more detail to description",
      details: "Add approximately #{needed} more characters to provide more context (optimal: 120-160 chars)."
    }
  elsif length > 160
    excess = length - 160
    recommendations << {
      category: "Meta Description",
      priority: :medium,
      action: "Condense description",
      details: "Reduce by approximately #{excess} characters to prevent truncation in search results."
    }
  end

  recommendations
end

#recommend_heading_improvements(headings_result) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/better_seo/validators/seo_recommendations.rb', line 87

def recommend_heading_improvements(headings_result)
  return [] if headings_result[:valid]

  recommendations = []
  h1_count = headings_result[:h1_count]

  if h1_count.zero?
    recommendations << {
      category: "Headings",
      priority: :high,
      action: "Add an H1 heading",
      details: "Every page should have exactly one H1 tag that describes the main topic."
    }
  elsif h1_count > 1
    recommendations << {
      category: "Headings",
      priority: :high,
      action: "Use only one H1 heading",
      details: "Found #{h1_count} H1 tags. Use H2-H6 for subheadings instead."
    }
  end

  if headings_result[:total_headings].zero?
    recommendations << {
      category: "Headings",
      priority: :medium,
      action: "Add heading structure",
      details: "Use headings (H1-H6) to organize content and improve readability."
    }
  end

  recommendations
end

#recommend_image_improvements(images_result) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/better_seo/validators/seo_recommendations.rb', line 121

def recommend_image_improvements(images_result)
  return [] if images_result[:valid]

  recommendations = []

  if images_result[:images_without_alt].positive?
    count = images_result[:images_without_alt]
    recommendations << {
      category: "Images",
      priority: :medium,
      action: "Add alt text to images",
      details: "#{count} image#{"s" if count > 1} missing alt text. Alt text improves accessibility and SEO."
    }
  end

  recommendations
end

#recommend_title_improvements(title_result) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/better_seo/validators/seo_recommendations.rb', line 19

def recommend_title_improvements(title_result)
  return [] if title_result[:valid]

  recommendations = []
  length = title_result[:length]

  if length.zero?
    recommendations << {
      category: "Title",
      priority: :high,
      action: "Add a page title",
      details: "A title tag is required for SEO. Aim for 30-60 characters."
    }
  elsif length < 30
    needed = 30 - length
    recommendations << {
      category: "Title",
      priority: :high,
      action: "Make title longer",
      details: "Add approximately #{needed} more characters to reach the optimal length (30-60 chars)."
    }
  elsif length > 60
    excess = length - 60
    recommendations << {
      category: "Title",
      priority: :medium,
      action: "Make title shorter",
      details: "Reduce by approximately #{excess} characters to stay within optimal length (30-60 chars)."
    }
  end

  recommendations
end