Skip to content

Commit 889f272

Browse files
committed
Add server driven meta tags
1 parent e3d7bd8 commit 889f272

File tree

11 files changed

+70
-18
lines changed

11 files changed

+70
-18
lines changed

app/controllers/application_controller.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ class ApplicationController < ActionController::Base
66
layout :set_layout
77

88
before_action :configure_permitted_parameters, if: :devise_controller?
9+
before_action :set_default_meta_tags
910

1011
inertia_share categories: -> {
1112
Category.includes(:topics).all.as_json(methods: :topics_count)
@@ -42,4 +43,15 @@ def configure_permitted_parameters
4243

4344
devise_parameter_sanitizer.permit(:account_update, keys: [ :username ])
4445
end
46+
47+
def set_default_meta_tags
48+
inertia_meta.add([
49+
{ title: "Pups & Pourovers" },
50+
{ name: "description", content: "Online home of the overcaffeinated dog enthusiast" },
51+
{ name: "viewport", content: "width=device-width,initial-scale=1" },
52+
{ name: "apple-mobile-web-app-capable", content: "yes" },
53+
{ name: "mobile-web-app-capable", content: "yes" },
54+
{ name: "application-name", content: "Pups & Pourovers" }
55+
])
56+
end
4557
end

app/controllers/categories_controller.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ def show
77
topics: { include: [ :user, :category, messages: { include: :user } ] }
88
])
99

10-
render inertia: { category: }
10+
render inertia: { category: }, meta: [
11+
{ title: "Category: #{category["name"]} - Pups & Pourovers" },
12+
{ name: "description", content: "Browse topics in the #{category["name"]} category on Pups & Pourovers" }
13+
]
1114
end
1215
end

app/controllers/my_topics_controller.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
class MyTopicsController < ApplicationController
22
before_action :verify_user
3+
34
def index
45
topics = Topic.includes(:user, :category, messages: :user)
56
.joins(:messages)
@@ -13,7 +14,10 @@ def index
1314
messages: { include: :user }
1415
])
1516

16-
render inertia: { topics: }
17+
render inertia: { topics: }, meta: [
18+
{ title: "My Topics - Pups & Pourovers" },
19+
{ name: "description", content: "View your topics on Pups & Pourovers" }
20+
]
1721
end
1822

1923
private

app/controllers/topics_controller.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ def index
99
messages: { include: :user }
1010
])
1111

12-
render inertia: { topics: }
12+
render inertia: { topics: }, meta: [
13+
{ title: "Topics - Pups & Pourovers" },
14+
{ name: "description", content: "Browse topics on Pups & Pourovers" }
15+
]
1316
end
1417

1518
def show
@@ -21,6 +24,9 @@ def show
2124
:category,
2225
messages: { include: :user }
2326
])
24-
render inertia: { topic: }
27+
render inertia: { topic: }, meta: [
28+
{ title: "#{topic["title"]} - Pups & Pourovers" },
29+
{ name: "description", content: "#{topic["title"]} - Pups & Pourovers" }
30+
]
2531
end
2632
end
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import React from 'react'
2+
import { Head, usePage } from '@inertiajs/react'
3+
import { Meta } from '../types'
4+
5+
const MetaTags = () => {
6+
const { _inertia_meta: meta } = usePage<{ _inertia_meta: Meta[] }>().props
7+
return (
8+
<Head>
9+
{meta.map((meta: Meta) => {
10+
const { tagName, innerContent, headKey, httpEquiv, ...attrs } = meta
11+
12+
let stringifiedInnerContent
13+
if (innerContent != null) {
14+
stringifiedInnerContent =
15+
typeof innerContent === 'string'
16+
? innerContent
17+
: JSON.stringify(innerContent)
18+
}
19+
20+
return React.createElement(tagName, {
21+
key: headKey,
22+
'head-key': headKey,
23+
...(httpEquiv ? { 'http-equiv': httpEquiv } : {}),
24+
...attrs,
25+
...(stringifiedInnerContent
26+
? { dangerouslySetInnerHTML: { __html: stringifiedInnerContent } }
27+
: {}),
28+
})
29+
})}
30+
</Head>
31+
)
32+
}
33+
34+
export default MetaTags

app/frontend/layouts/AppLayout.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
} from '@heroicons/react/24/outline'
99
import { User } from '@/types'
1010
import Sidebar from "@/components/Sidebar";
11+
import MetaTags from '../components/MetaTags'
1112

1213
interface AppLayoutProps {
1314
children: ReactNode
@@ -21,6 +22,7 @@ export default function AppLayout({ children }: AppLayoutProps) {
2122

2223
return (
2324
<div className="flex h-screen bg-gray-50">
25+
<MetaTags />
2426
<Sidebar isOpen={sidebarOpen} />
2527

2628
<div className="flex-1 flex flex-col overflow-hidden">

app/frontend/pages/landing/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ import { Menu, MenuButton, MenuItems, MenuItem } from '@headlessui/react'
33
import { ChevronDownIcon } from '@heroicons/react/24/outline'
44
import { Category, User } from '../../types'
55
import Luna from '../../assets/luna.gif'
6+
import MetaTags from '../../components/MetaTags'
67

78
export default function LandingIndex() {
89
const { props: { categories, current_user: currentUser } } = usePage<{ categories: Category[], current_user: User }>();
910

1011
return (
1112
<>
13+
<MetaTags />
1214
<nav className="fixed top-0 left-0 right-0 z-50 bg-white/80 backdrop-blur-md border-b border-gray-200/50">
1315
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
1416
<div className="flex items-center justify-between h-16">

app/frontend/pages/my_topics/index.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
import { Head } from '@inertiajs/react'
21
import AppLayout from '../../layouts/AppLayout'
32
import { Topic } from '../../types'
43
import TopicsTable from '../../components/TopicsTable'
54

65
function MyTopicsIndex({ topics }: { topics: Topic[] }) {
76
return (
87
<AppLayout>
9-
<Head title="My Topics - Pups & Pourovers" />
10-
118
<div className="max-w-7xl mx-auto">
129
<div className="bg-white shadow-sm rounded-lg overflow-hidden">
1310
<TopicsTable topics={topics} />

app/frontend/pages/topics/index.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
import { Head } from '@inertiajs/react'
21
import AppLayout from '../../layouts/AppLayout'
32
import { Topic } from '../../types'
43
import TopicsTable from '../../components/TopicsTable'
54

65
function TopicsIndex({ topics }: { topics: Topic[] }) {
76
return (
87
<AppLayout>
9-
<Head title="Topics - Pups & Pourovers" />
10-
118
<div className="max-w-7xl mx-auto">
129
<div className="bg-white shadow-sm rounded-lg overflow-hidden">
1310
<TopicsTable topics={topics} />

app/frontend/pages/topics/show.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Head, Form } from '@inertiajs/react'
1+
import { Form } from '@inertiajs/react'
22
import AppLayout from '../../layouts/AppLayout'
33
import { Topic, Message, User } from '../../types'
44
import LexicalRichTextEditor from '../../components/LexicalRichTextEditor'
@@ -49,8 +49,6 @@ function TopicsShow({ topic, current_user: currentUser }: { topic: Topic, curren
4949

5050
return (
5151
<AppLayout>
52-
<Head title={`${title} - Pups & Pourovers`} />
53-
5452
<div className="max-w-4xl mx-auto">
5553
<div className="bg-white rounded-lg shadow-sm border border-gray-200 p-6 mb-6">
5654
<div className="flex items-start justify-between">

0 commit comments

Comments
 (0)