끄적이고 기록하는 나의 블로그

[Vuejs] vue-meta를 활용하여 meta 태그 dynamical 속성 정의하기 본문

프로그래밍/FE engineering

[Vuejs] vue-meta를 활용하여 meta 태그 dynamical 속성 정의하기

toeun 2023. 12. 21. 20:26

 

one source로 멀티 도메인 서비스를 하는 경우, 드러날 필요 없는 조건으로 결과물을 달리 해야하는 경우가 있다.

 

javascript 영역 말고도, DOM에서도 마찬가지이다.

Vue Component에서의 DOM에 대한 조건문 제어는 경우에 따라 다르지만 Vue Lifecycle hook 함수를 통해 처리하는 경우가 많다.

하지만 <head> 태그라던지, index.html 영역에 있는 DOM에 대한 제어는 생각보다 깔끔한 처리가 어렵다.

 

시도해볼 수 있는 방법은 if 조건문 또는 조건연산자로 <script> 내에서 처리할 수 있지만,

복잡한 case의 경우 코드에 대한 가독성이 좋지 않아 운영 관점에서도 어려움을 느낄 수 있다.

 

그 중에서도 서비스 도메인에 대한 웹 페이지 정보를 담고있는 meta의 경우는 더욱 그러하다.

(아래의 내용 참고)

 

HTML에서 <meta>는 <meta>는 <head>안에서 사용하는 meta data를 설정하기 위한 태그다. 여기서 meta data란, 데이터를 설명하는 데이터다.

meta data를 정의하면 브라우저나 검색 엔진, 다른 웹 서비스에서 해당 웹 페이지에 대한 meta data를 토대로 분석, 페이지 최적화의 용도로 사용하게 된다. 실제 페이지에는 보여지지 않고 검색 엔진에서 읽혀지는 하나의 헤더다. SEO(Search Engine Optimization)에 신경 써야하는 페이지들은 필수로 적용되어 있다.

브라우저 화면에서 F12를 눌러 개발자 도구를 켠 후 Element 탭에서 <head> 태그를 펼쳐보면, <meta …> 라고 정의된 태그들이 있다. 이 태그들이 검색 엔진에게 meta 정보를 넘겨주면서 SEO에 도움을 주게 되는 원리이다.

Vue.js는 SPA(Single Page Application)로 페이지가 단 한개 뿐인 웹 어플리케이션이다. SSR 방식이었다면 페이지를 이동할 때마다 새로운 페이지를 불러오기 때문에 페이지마다 <meta> 를 새로 정의해주면 웹 크롤러가 알아서 정보를 수집했을 것이다.

하지만 vue에서는 vue-router로 페이지를 이동하면서 동적으로 <meta> 를 변화시켜 주어야한다. 이는 작업에 비효율적이며, 채택하고 싶지 않은 방식이다. 다행히도 npm에서는 vue-meta 라는 npm 모듈로 해결할 수 있다. react 진영에서는 react-helmet이 이 역할을 한다.

 

 

소개와 같이 vue-meta 라는 npm 모듈을 통해 meta 태그에 dynamical 속성 값을 정의할 수 있다.

방법은 하기와 같다.

 

 

1. 설치

> npm install vue-meta --save

 

 

2. main.js 적용

import Meta from 'vue-meta'

Vue.use(Meta)
// 옵션 변경 필요시 작성
/* Vue.use(Meta, {
  keyName: 'metaInfo',
  attribute: 'data-vue-meta',
  ssrAttribute: 'data-vue-meta-server-rendered',
  tagIDKeyName: 'vmid',
  refreshOnceOnNavigation: true
}) */

 

⇒ 옵션 정보

  • keyName : String 형식, component 에서 meta를 지정해줄 때 keyName에 지정된 이름으로 부를 수 있다.
  • attribute : String 형식, 실제적으로 meta 태그에 vue-meta를 관리한다는 attribute를 구분 값으로 심어준다.
  • tagIDKeyName : String 형식, 이 구분 값으로 meta 태그를 새로 만들어 쌓는게 아니라 name에 따라 meta 태그를 변화시킨다.

 

3. 컴포넌트에 적용

export default {
  name: 'App',
  metaInfo: {
    meta: [
      {
        property: 'og:title',
        content: process.env.VUE_APP_PRODUCTION_NAME
      },
      {
        property: 'og:type',
        content: 'website'
      },
      {
        property: 'og:url',
        content: process.env.VUE_APP_PRODUCTION_NAME === 'AAA' ? 'https://a.aaa.com' : 'https://b.bbb.com'
      },
      {
        property: 'og:image',
        content: process.env.VUE_APP_PRODUCTION_NAME === 'AAA' ? `${process.env.BASE_URL}aOG.png` : `${process.env.BASE_URL}bOG.png`
      },
    ]
  },
}

 

 

⇒ 특정 컴포넌트에만 적용한다면 해당 컴포넌트 vue 파일에 구현하고, 전체 컴포넌트에 영향을 준다면 App.vue 파일에 구현한다.

⇒ 위 예시 코드는 Vue 환경변수로 정의한 build mode별 상이한 content를 구성하도록 구현된 부분이다.

 

 

4. index.html

컴포넌트별 분기가 필요하지 않은 meta 데이터는 index.html에 고정으로 작성한다.

<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="user-scalable=yes,width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=2.0">

 

 

 

5. 결과물 비교

index.html에 모두 고정으로 넣은 경우

 

vue-meta 모듈 적용으로 넣은 경우