Skip to content

Commit 8c0da3b

Browse files
committed
Meta 태그 기능 추가
1 parent ef127be commit 8c0da3b

File tree

3 files changed

+185
-29
lines changed

3 files changed

+185
-29
lines changed

README.md

Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,109 @@ php artisan vendor:publish --tag=essentials-entry-config
2626

2727
## 기능
2828

29-
### 1. 사이트맵 생성
29+
### 1. 메타 태그 관리
30+
31+
이 패키지는 [butschster/meta-tags](https://github.com/butschster/LaravelMetaTags) 패키지를 기반으로 하여 SEO를 위한 메타 태그를 자동으로 관리합니다. 설정된 내용에 따라 사이트 전체에 필요한 메타 태그가 자동으로 적용됩니다.
32+
33+
#### 설정
34+
35+
`config/essentials-entry.php` 파일에서 메타 태그 설정을 변경할 수 있습니다:
36+
37+
```php
38+
'meta-tags' => [
39+
'og' => [
40+
'type' => 'website',
41+
'image' => 'https://s-lol-web.op.gg/images/reverse.rectangle.png',
42+
],
43+
'images' => [
44+
'touch_icon' => '/apple-touch-icon.png',
45+
],
46+
],
47+
```
48+
49+
#### 다국어 지원
50+
51+
메타 태그 텍스트는 다국어 파일에서 가져옵니다. 각 언어 폴더에 `seo.php` 파일을 생성하고 다음과 같이 구성하세요:
52+
53+
```php
54+
// lang/ko/seo.php
55+
return [
56+
'title' => '사이트 제목',
57+
'description' => '사이트 설명',
58+
'keywords' => '키워드1, 키워드2, 키워드3',
59+
];
60+
```
61+
62+
#### 사용 방법
63+
64+
블레이드 템플릿의 `<head>` 섹션에 다음 코드를 추가하세요:
65+
66+
```php
67+
{!! Meta::toHtml() !!}
68+
```
69+
70+
기존 `<title>Laravel</title>` 태그 대신 위 코드를 사용하면 다음과 같은 메타 태그가 자동으로 생성됩니다:
71+
72+
```html
73+
<title>Laravel</title>
74+
<script>
75+
window.appTitle = "seo.title";
76+
window.locale = "en";
77+
window.baseUrl = "http://127.0.0.1:8000";
78+
</script>
79+
<link rel="icon" type="image/x-icon" href="favicon.ico" />
80+
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
81+
<meta name="description" content="seo.description" />
82+
<meta name="keywords" content="seo.keywords" />
83+
<link
84+
rel="sitemap"
85+
type="application/xml"
86+
title="Sitemap"
87+
href="http://127.0.0.1:8000/sitemap.xml"
88+
/>
89+
<link rel="canonical" href="http://127.0.0.1:8000/about" />
90+
<link rel="alternate" hreflang="x-default" href="http://127.0.0.1:8000/about" />
91+
<link rel="alternate" hreflang="en" href="http://127.0.0.1:8000/about" />
92+
<link rel="alternate" hreflang="es" href="http://127.0.0.1:8000/es/about" />
93+
<link rel="alternate" hreflang="ja" href="http://127.0.0.1:8000/ja/about" />
94+
<link rel="alternate" hreflang="ko" href="http://127.0.0.1:8000/ko/about" />
95+
<link
96+
rel="alternate"
97+
hreflang="zh-cn"
98+
href="http://127.0.0.1:8000/zh-cn/about"
99+
/>
100+
<link
101+
rel="alternate"
102+
hreflang="zh-tw"
103+
href="http://127.0.0.1:8000/zh-tw/about"
104+
/>
105+
<meta property="og:type" content="website" />
106+
<meta property="og:site_name" content="seo.title" />
107+
<meta property="og:locale" content="en" />
108+
<meta
109+
property="og:image"
110+
content="https://s-lol-web.op.gg/images/reverse.rectangle.png"
111+
/>
112+
<meta property="og:locale:alternate" content="en" />
113+
<meta property="og:locale:alternate" content="es" />
114+
<meta property="og:locale:alternate" content="ja" />
115+
<meta property="og:locale:alternate" content="ko" />
116+
<meta property="og:locale:alternate" content="zh-cn" />
117+
<meta property="og:locale:alternate" content="zh-tw" />
118+
<meta property="og:url" content="http://127.0.0.1:8000/about" />
119+
<meta charset="utf-8" />
120+
<meta name="viewport" content="width=device-width, initial-scale=1" />
121+
```
122+
123+
#### Inertia.js와 함께 사용하기
124+
125+
Inertia.js를 사용하는 경우 다음과 같이 설정하여 함께 사용할 수 있습니다:
126+
127+
```php
128+
{!! preg_replace('/<title>(.*?)<\/title>/', '<title inertia>$1</title>', Meta::toHtml()) !!}
129+
```
130+
131+
### 2. 사이트맵 생성
30132

31133
이 패키지를 설치하면 자동으로 사이트맵을 생성하고 스케줄링됩니다. 단, 어떻게 사이트맵을 생성할 것인지 설정 파일에서 잘 설정해주어야합니다.
32134

@@ -230,7 +332,7 @@ composer test
230332

231333
다음 기능들은 향후 구현 예정입니다:
232334

233-
- 메타 태그 관리: Inertia.js와 통합된 메타 태그 관리 기능
335+
- 메타 태그 관리: SEO 및 소셜 미디어를 위한 메타 태그 자동 관리 (완료)
234336
- JSON-LD 스키마 지원: 구조화된 데이터를 위한 JSON-LD 스키마 추가
235337
- 변경한 언어코드를 위한 리다이렉트 기능
236338

config/essentials-entry.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,35 @@
55
|--------------------------------------------------------------------------
66
| Favicon Configuration
77
|--------------------------------------------------------------------------
8+
| enabled 를 true 로 설정하면 아래 Meta Tag 설정으로 자동으로 favicon 이 삽입됩니다.
89
*/
910
'favicon' => [
1011
'enabled' => true,
11-
'source_path' => null, // null이면 패키지 내부 파비콘 사용
12+
'source_path' => null, // null이면 op.gg 파란색 기본 파비콘 사용
1213
'path_rewrite' => 'favicon.ico',
1314
'cache' => [
1415
'enabled' => true,
1516
'duration' => 31536000, // 1년
1617
],
1718
],
1819

20+
/*
21+
|--------------------------------------------------------------------------
22+
| Meta Tags Configuration
23+
|--------------------------------------------------------------------------
24+
| app.blade.php 에서 <title>Laravel</title> 대신 {!! Meta::toHtml() !!}를 하면
25+
| 메타 태그가 자동으로 들어갑니다.
26+
*/
27+
'meta-tags' => [
28+
'og' => [
29+
'type' => 'website',
30+
'image' => 'https://s-lol-web.op.gg/images/reverse.rectangle.png',
31+
],
32+
'images' => [
33+
'touch_icon' => '/apple-touch-icon.png',
34+
],
35+
],
36+
1937
/*
2038
|--------------------------------------------------------------------------
2139
| Sitemap Configuration

src/Providers/MetaTagsServiceProvider.php

Lines changed: 62 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@
77
use Butschster\Head\MetaTags\Meta;
88
use Butschster\Head\MetaTags\Entities\JavascriptVariables;
99
use Butschster\Head\Packages\Entities\OpenGraphPackage;
10+
use Butschster\Head\Packages\Entities\TwitterCardPackage;
1011
use Butschster\Head\Providers\MetaTagsApplicationServiceProvider as ServiceProvider;
1112
use Illuminate\Support\Facades\App;
1213
use Illuminate\Support\Facades\Config;
1314
use Illuminate\Support\Facades\File;
1415
use Illuminate\Support\Facades\Lang;
1516
use Illuminate\Support\Facades\Log;
1617
use Illuminate\Support\Facades\Route;
18+
use Illuminate\Support\Str;
19+
use OPGG\LaravelEssentialsEntry\Facades\EssentialsEntry as EssentialsEntryFacade;
1720
use OPGG\LaravelEssentialsEntry\Http\Middleware\DetectLanguage;
1821

1922
class MetaTagsServiceProvider extends ServiceProvider
@@ -31,17 +34,17 @@ protected function checkTranslationKey(string $key): void
3134
$defaultLocale = Config::get('essentials-entry.language.default', 'en');
3235
if (!Lang::has($key, $defaultLocale)) {
3336
$langPath = lang_path($defaultLocale);
34-
$sitePath = "{$langPath}/site.php";
35-
36-
if (!File::exists($sitePath)) {
37+
$seoPath = "{$langPath}/seo.php";
38+
39+
if (!File::exists($seoPath)) {
3740
Log::warning(
38-
"[메타 태그] {$defaultLocale}/site.php 파일이 존재하지 않습니다. " .
41+
"[메타 태그] {$defaultLocale}/seo.php 파일이 존재하지 않습니다. " .
3942
"SEO를 위해 다음과 같은 형식으로 파일을 생성해주세요:\n" .
4043
"return [\n 'title' => '',\n 'description' => '',\n 'keywords' => '',\n];\n"
4144
);
4245
} else {
4346
Log::warning(
44-
"[메타 태그] {$key} 번역 키가 {$defaultLocale}/site.php 파일에 존재하지 않습니다. " .
47+
"[메타 태그] {$key} 번역 키가 {$defaultLocale}/seo.php 파일에 존재하지 않습니다. " .
4548
"SEO를 위해 해당 키를 추가해주세요."
4649
);
4750
}
@@ -56,14 +59,20 @@ protected function registerMeta(): void
5659
$this->app['config']
5760
);
5861

62+
// 설정 값 가져오기
63+
$metaConfig = Config::get('essentials-entry.meta-tags', []);
64+
$ogConfig = $metaConfig['og'] ?? [];
65+
$imagesConfig = $metaConfig['images'] ?? [];
66+
5967
// 번역 키 확인
60-
$this->checkTranslationKey('site.title');
61-
$this->checkTranslationKey('site.description');
62-
$this->checkTranslationKey('site.keywords');
68+
$this->checkTranslationKey('seo.title');
69+
$this->checkTranslationKey('seo.description');
70+
$this->checkTranslationKey('seo.keywords');
6371

64-
$meta->setTitle(__('site.title'));
72+
// 기본 태그 설정
73+
$meta->setTitle(__('seo.title'));
6574
$meta->addTag('variables', new JavascriptVariables([
66-
'appTitle' => __('site.title'),
75+
'appTitle' => __('seo.title'),
6776
]));
6877

6978
// 파비콘 설정
@@ -72,18 +81,30 @@ protected function registerMeta(): void
7281
$meta->setFavicon($faviconConfig['path_rewrite']);
7382
}
7483

75-
$meta->setDescription(__('site.description'));
76-
$meta->setKeywords(__('site.keywords'));
77-
$meta->setRobots('index,follow');
78-
$meta->setViewport('width=device-width, initial-scale=1');
79-
$meta->setCharset('utf-8');
84+
// 애플 터치 아이콘 설정
85+
if (isset($imagesConfig['touch_icon']) && !empty($imagesConfig['touch_icon'])) {
86+
$meta->addLink('apple-touch-icon', [
87+
'rel' => 'apple-touch-icon',
88+
'href' => $imagesConfig['touch_icon'],
89+
]);
90+
}
91+
92+
// 기본 메타 태그 설정
93+
$meta->setDescription(__('seo.description'));
94+
$meta->setKeywords(__('seo.keywords'));
8095

81-
$og = new OpenGraphPackage('');
82-
$og->setType('website')
83-
->setSiteName(Config::get('app.name'))
96+
// 오픈 그래프 패키지 설정
97+
$og = new OpenGraphPackage('og-package');
98+
$og->setType($ogConfig['type'] ?? 'website')
99+
->setSiteName(__('seo.title'))
84100
->setLocale(App::getLocale());
85101

86-
$supportedLocales = array_keys(Config::get('essentials-entry.language.supported', []));
102+
if (isset($ogConfig['image']) && !empty($ogConfig['image'])) {
103+
$og->addImage((string) url($ogConfig['image']));
104+
}
105+
106+
// 다국어 설정
107+
$supportedLocales = EssentialsEntryFacade::getSupportedLanguages();
87108
foreach ($supportedLocales as $locale) {
88109
$og->addAlternateLocale($locale);
89110
}
@@ -98,38 +119,53 @@ protected function registerMeta(): void
98119
]);
99120
}
100121

101-
// Get current route information
122+
// 현재 라우트 정보 가져오기
102123
if (Route::isLocalized() || Route::isFallback()) {
103-
// Set canonical URL for current locale
124+
// 현재 로케일에 대한 표준 URL 설정
104125
try {
105126
$currentLocale = App::getLocale();
106127
$canonicalUrl = Route::localizedUrl($currentLocale);
107128
$meta->setCanonical($canonicalUrl);
108129
$og->setUrl($canonicalUrl);
109130
} catch (\Exception $e) {
110-
// Skip if URL generation fails
131+
// URL 생성에 실패하면 스킵
111132
}
112133

113-
// Add x-default first
134+
// x-default를 먼저 추가
114135
try {
115-
$url = Route::localizedUrl('en'); // 영어를 기본값으로 설정
136+
$defaultLocale = Config::get('essentials-entry.language.default', 'en');
137+
$url = Route::localizedUrl($defaultLocale);
116138
$meta->setHrefLang('x-default', $url);
117139
} catch (\Exception $e) {
118-
// Skip if URL generation fails
140+
// URL 생성에 실패하면 스킵
119141
}
120142

143+
// 각 지원 로케일에 대한 대체 URL 추가
121144
foreach ($supportedLocales as $locale) {
122145
try {
123146
$url = Route::localizedUrl($locale);
124147
$meta->setHrefLang($locale, $url);
125148
} catch (\Exception $e) {
126-
// Skip if URL generation fails for this locale
149+
// 이 로케일에 대한 URL 생성에 실패하면 스킵
127150
continue;
128151
}
129152
}
130153
}
131154

155+
// 전역 JavaScript 변수
156+
$jsVariables = [
157+
'appTitle' => __('seo.title'),
158+
'locale' => App::getLocale(),
159+
'baseUrl' => url('/')
160+
];
161+
162+
// JavaScript 변수 추가
163+
$meta->addTag('variables', new JavascriptVariables($jsVariables));
164+
165+
// OG 패키지 등록
132166
$meta->registerPackage($og);
167+
168+
// 초기화 (기본값 가져오기 및 태그 생성, 기본 패키지 포함)
133169
$meta->initialize();
134170

135171
return $meta;

0 commit comments

Comments
 (0)