Skip to content

Commit

Permalink
feat(seo): add title and description to meta tags
Browse files Browse the repository at this point in the history
  • Loading branch information
VChet committed Oct 18, 2024
1 parent 1b8ea2f commit 1c97180
Show file tree
Hide file tree
Showing 9 changed files with 388 additions and 286 deletions.
11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,33 +18,34 @@
},
"dependencies": {
"@intlify/unplugin-vue-i18n": "^5.2.0",
"@unhead/vue": "^1.11.10",
"@vitejs/plugin-vue": "^5.1.4",
"@vueuse/core": "^11.1.0",
"dayjs": "^1.11.13",
"v-wave": "^3.0.2",
"vite": "^5.4.8",
"vite": "^5.4.9",
"vite-plugin-pwa": "^0.20.5",
"vue": "^3.5.12",
"vue-i18n": "^10.0.4",
"vue-router": "^4.4.5"
},
"devDependencies": {
"@antfu/eslint-config": "^3.7.3",
"@antfu/eslint-config": "^3.8.0",
"@localazy/cli": "^1.7.14",
"@stylistic/stylelint-plugin": "^3.1.1",
"@tabler/icons-vue": "^3.19.0",
"@types/node": "^22.7.5",
"@types/node": "^22.7.6",
"eslint": "^9.12.0",
"postcss-html": "^1.7.0",
"postcss-scss": "^4.0.9",
"sass": "^1.79.5",
"sass": "^1.80.2",
"stylelint": "^16.10.0",
"stylelint-config-recess-order": "^5.1.1",
"stylelint-config-standard-scss": "^13.1.0",
"stylelint-declaration-block-no-ignored-properties": "^2.8.0",
"stylelint-order": "^6.0.4",
"stylelint-rem-over-px": "^1.0.1",
"typescript": "^5.5.4",
"typescript": "^5.6.3",
"vue-tsc": "^2.1.6",
"workbox-core": "^7.1.0",
"workbox-precaching": "^7.1.0",
Expand Down
596 changes: 319 additions & 277 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions src/constants/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ const messages: I18nOptions["messages"] = {
onboarding: "Onboarding",
search: "Search",
calendar: "Calendar",
birthsigns: "Birthsigns",
birthsign: "Birthsign",
holiday: "Holiday",
summoningDay: "Summoning Day",
settings: "Settings"
Expand Down Expand Up @@ -57,6 +59,8 @@ const messages: I18nOptions["messages"] = {
onboarding: "Приветствие",
search: "Поиск",
calendar: "Календарь",
birthsigns: "Знаки рождения",
birthsign: "Знак рождения",
holiday: "Праздник",
summoningDay: "День вызова даэдра",
settings: "Настройки"
Expand Down
14 changes: 14 additions & 0 deletions src/helpers/router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { i18n } from "@/main";

interface ComposeTitleOptions {
/** Pass raw text instead of translation token */
raw?: boolean
}
export function composeTitle(prependText: string | undefined, options: ComposeTitleOptions = {}) {
let title = i18n.global.t("router.title");
if (prependText) {
if (!options.raw) prependText = i18n.global.t(prependText);
title = `${prependText} | ${title}`;
}
return title;
}
4 changes: 4 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { createApp } from "vue";
import { createI18n } from "vue-i18n";
import { createHead } from "@unhead/vue";
import VWave from "v-wave";
import messages from "@/constants/messages";
import { useSettingsStore } from "@/store/settings";
Expand All @@ -14,11 +15,14 @@ export const i18n = createI18n({
messages
});

const head = createHead();

const { settings, setLocale } = useSettingsStore();
setLocale(settings.value.locale);

createApp(App)
.use(i18n)
.use(router)
.use(head)
.use(VWave, {})
.mount("#app");
6 changes: 2 additions & 4 deletions src/router.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createRouter, createWebHistory } from "vue-router";
import { i18n } from "./main";
import { composeTitle } from "./helpers/router";
import { useSettingsStore } from "./store/settings";

const OnboardingView = () => import("@/views/OnboardingView.vue");
Expand Down Expand Up @@ -115,9 +115,7 @@ router.beforeEach(() => {
});
router.afterEach((to) => {
const token = to.matched[0].meta.titleToken;
document.title = token ?
`${i18n.global.t(token)} | ${i18n.global.t("router.title")}` :
i18n.global.t("router.title");
document.title = composeTitle(token);
});

export default router;
13 changes: 13 additions & 0 deletions src/views/BirthsignView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,27 @@ import { computed } from "vue";
import { useShare } from "@vueuse/core";
import { useRoute } from "vue-router";
import { IconShare3 } from "@tabler/icons-vue";
import { useHead } from "@unhead/vue";
import { composeMonthNameFromDataEntry, isValidMonthIndex } from "@/helpers/date";
import { composeTitle } from "@/helpers/router";
import { useEventsStore } from "@/store/events";
import CommonHeader from "@/components/CommonHeader.vue";
const route = useRoute();
const { birthsigns } = useEventsStore();
const birthsign = computed(() => birthsigns.get(route.params.month?.toString()));
const title = computed<string>(() => {
if (!birthsign.value) return composeTitle(route.meta.titleToken);
return composeTitle(birthsign.value.name, { raw: true });
});
useHead({
title,
meta: () => [
{ name: "description", content: birthsign.value?.description }
]
});
const { share, isSupported: isShareSupported } = useShare();
function shareBirthsign(): void {
if (!birthsign.value) return;
Expand Down
13 changes: 13 additions & 0 deletions src/views/HolidayView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import { computed } from "vue";
import { useShare } from "@vueuse/core";
import { useRoute } from "vue-router";
import { IconShare3 } from "@tabler/icons-vue";
import { useHead } from "@unhead/vue";
import { composeTitle } from "@/helpers/router";
import { useEventsStore } from "@/store/events";
import CommonHeader from "@/components/CommonHeader.vue";
Expand All @@ -39,6 +41,17 @@ const date = route.query.date?.toString();
const { holidays } = useEventsStore();
const event = computed(() => (date ? holidays.get(date) : null));
const title = computed<string>(() => {
if (!event.value) return composeTitle(route.meta.titleToken);
return composeTitle(event.value.name, { raw: true });
});
useHead({
title,
meta: () => [
{ name: "description", content: event.value?.description }
]
});
const { share, isSupported: isShareSupported } = useShare();
function shareEvent(): void {
if (!event.value) return;
Expand Down
13 changes: 13 additions & 0 deletions src/views/SummoningDayView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import { computed } from "vue";
import { useShare } from "@vueuse/core";
import { useRoute } from "vue-router";
import { IconShare3 } from "@tabler/icons-vue";
import { useHead } from "@unhead/vue";
import { composeTitle } from "@/helpers/router";
import { useEventsStore } from "@/store/events";
import CommonHeader from "@/components/CommonHeader.vue";
Expand All @@ -40,6 +42,17 @@ const date = route.query.date?.toString();
const { summoningDays } = useEventsStore();
const event = computed(() => (date ? summoningDays.get(date) : null));
const title = computed<string>(() => {
if (!event.value) return composeTitle(route.meta.titleToken);
return composeTitle(event.value.name, { raw: true });
});
useHead({
title,
meta: () => [
{ name: "description", content: event.value?.description }
]
});
const { share, isSupported: isShareSupported } = useShare();
function shareEvent(): void {
if (!event.value) return;
Expand Down

0 comments on commit 1c97180

Please sign in to comment.