Dependency refresh and cleanup
This commit is contained in:
parent
6300d6746a
commit
c70f9013f5
22 changed files with 1858 additions and 3392 deletions
|
@ -1,7 +0,0 @@
|
||||||
{
|
|
||||||
"root": true,
|
|
||||||
"extends": "awzzm-vue",
|
|
||||||
"rules": {
|
|
||||||
"vue/no-reserved-component-names": "off"
|
|
||||||
}
|
|
||||||
}
|
|
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -1,8 +1,7 @@
|
||||||
.idea/
|
/.idea/
|
||||||
/node_modules/
|
/node_modules/
|
||||||
/dist/
|
/dist/
|
||||||
/.vite-ssg-temp/
|
/.vite-ssg-temp/
|
||||||
|
|
||||||
*.log
|
*.log
|
||||||
.env
|
*.env
|
||||||
|
|
2
.nvmrc
2
.nvmrc
|
@ -1 +1 @@
|
||||||
16.11.0
|
22
|
|
@ -8,7 +8,7 @@
|
||||||
<link rel="stylesheet" href="/node_modules/@fontsource/plus-jakarta-sans/400.css">
|
<link rel="stylesheet" href="/node_modules/@fontsource/plus-jakarta-sans/400.css">
|
||||||
<link rel="stylesheet" href="/node_modules/@fontsource/syne/700.css">
|
<link rel="stylesheet" href="/node_modules/@fontsource/syne/700.css">
|
||||||
<link rel="stylesheet" href="/node_modules/@fontsource/plus-jakarta-sans/700.css">
|
<link rel="stylesheet" href="/node_modules/@fontsource/plus-jakarta-sans/700.css">
|
||||||
<meta name="description" content="freelance software developer, graphic design enthusiast and hobby photographer">
|
<meta name="description" content="freelance software developer, photographer, musician">
|
||||||
<link rel="icon" type="image/png" href="/favicon.ico">
|
<link rel="icon" type="image/png" href="/favicon.ico">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
12
netlify.toml
12
netlify.toml
|
@ -1,12 +0,0 @@
|
||||||
[build.environment]
|
|
||||||
# bypass npm auto install
|
|
||||||
NPM_FLAGS = "--version"
|
|
||||||
|
|
||||||
[build]
|
|
||||||
publish = "dist"
|
|
||||||
command = "npx pnpm i --store=node_modules/.pnpm-store && npx pnpm run build"
|
|
||||||
|
|
||||||
[[redirects]]
|
|
||||||
from = "/*"
|
|
||||||
to = "/index.html"
|
|
||||||
status = 200
|
|
46
package.json
46
package.json
|
@ -1,34 +1,36 @@
|
||||||
{
|
{
|
||||||
"name": "moritzruth.de",
|
"name": "moritzruth.de",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite --host",
|
"dev": "vite --host",
|
||||||
"build": "vite-ssg build",
|
"build": "vite-ssg build",
|
||||||
"start": "vite preview",
|
"start": "vite preview"
|
||||||
"lint": "eslint . --fix --ignore-path .gitignore"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-vue": "^2.0.1",
|
"@vitejs/plugin-vue": "^5.2.1",
|
||||||
"@vue/compiler-sfc": "^3.1.1",
|
"@vue/compiler-sfc": "^3.5.13",
|
||||||
"eslint": "^7.32.0",
|
"typescript": "^5.7.3",
|
||||||
"eslint-config-awzzm-vue": "^2.0.1",
|
"vite": "^6.1.0",
|
||||||
"typescript": "^4.5.4",
|
"vite-plugin-pages": "^0.32.4",
|
||||||
"vite": "^2.3.7",
|
"vite-plugin-windicss": "^1.9.4",
|
||||||
"vite-plugin-pages": "^0.19.4",
|
"windicss": "^3.5.6"
|
||||||
"vite-plugin-windicss": "^1.0.4",
|
|
||||||
"windicss": "^3.2.1"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource/plus-jakarta-sans": "^4.5.0",
|
"@fontsource/plus-jakarta-sans": "^5.1.1",
|
||||||
"@fontsource/syne": "^4.5.0",
|
"@fontsource/syne": "^5.1.1",
|
||||||
"@iconify/json": "1.1.444",
|
"@iconify/json": "^2.2.306",
|
||||||
"@vueuse/core": "^7.2.2",
|
"@vueuse/core": "^12.5.0",
|
||||||
"@vueuse/head": "^0.5.1",
|
"@vueuse/head": "^2.0.0",
|
||||||
"blobs": "^2.2.1-beta.1",
|
"blobs": "^2.3.0-beta.2",
|
||||||
"ohmyfetch": "^0.4.11",
|
"unplugin-icons": "^22.0.0",
|
||||||
"unplugin-icons": "^0.12.23",
|
"vite-ssg": "^25.0.0",
|
||||||
"vite-ssg": "^0.17.2",
|
"vue": "^3.5.13",
|
||||||
"vue": "^3.2.26",
|
"vue-router": "^4.5.0"
|
||||||
"vue-router": "^4.0.12"
|
},
|
||||||
|
"pnpm": {
|
||||||
|
"onlyBuiltDependencies": [
|
||||||
|
"esbuild"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
4887
pnpm-lock.yaml
generated
4887
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
|
@ -1,2 +0,0 @@
|
||||||
/.well-known/*
|
|
||||||
Access-Control-Allow-Origin: *
|
|
|
@ -1,9 +0,0 @@
|
||||||
# Old domain
|
|
||||||
https://moritz-ruth.de/* https://moritzruth.de/:splat 301!
|
|
||||||
|
|
||||||
# External
|
|
||||||
/matrix https://matrix.to/#/@moritz:deltaa.xyz
|
|
||||||
/twitter https://twitter.com/moritzruth
|
|
||||||
|
|
||||||
# Internal
|
|
||||||
/kontakt /contact
|
|
2
redirects.txt
Normal file
2
redirects.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/kontakt /contact
|
||||||
|
/matrix https://matrix.to/#/@moritz:deltaa.xyz
|
|
@ -1,52 +0,0 @@
|
||||||
<template>
|
|
||||||
<NotFoundPage v-if="post === null" object-name="post" back-target="/blog"/>
|
|
||||||
<TopBarLayout v-else title="Blog" back-target="/blog">
|
|
||||||
<article>
|
|
||||||
<h1 class="font-bold text-3xl sm:text-3xl sm:text-center font-special">
|
|
||||||
{{ post.title }}
|
|
||||||
</h1>
|
|
||||||
<XSpacer v="4"/>
|
|
||||||
<div class="flex justify-center -sm:flex-col -sm:space-y-1 -sm:pt-2 sm:space-x-3 text-sm sm:text-base">
|
|
||||||
<div>
|
|
||||||
Published at {{ post.published_at.slice(0, 10) }}
|
|
||||||
</div>
|
|
||||||
<div class="-sm:hidden">
|
|
||||||
|
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Reading time: {{ post.reading_time_minutes }} minute{{ post.reading_time_minutes === 1 ? "" : "s" }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<XSpacer v="8"/>
|
|
||||||
<Prose v-html="html"/>
|
|
||||||
</article>
|
|
||||||
</TopBarLayout>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style module>
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { useRoute } from "vue-router"
|
|
||||||
import { getPostBySlug } from "../posts"
|
|
||||||
import TopBarLayout from "./TopBarLayout.vue"
|
|
||||||
import Prose from "./Prose.vue"
|
|
||||||
import XSpacer from "./XSpacer.vue"
|
|
||||||
import NotFoundPage from "./NotFoundPage.vue"
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "BlogPostPageContent",
|
|
||||||
components: { NotFoundPage, XSpacer, Prose, TopBarLayout },
|
|
||||||
async setup() {
|
|
||||||
const route = useRoute()
|
|
||||||
const post = await getPostBySlug(route.params.slug as string)
|
|
||||||
|
|
||||||
return {
|
|
||||||
post,
|
|
||||||
// Yep, that's awful code
|
|
||||||
html: post?.body_html?.replaceAll("h2>", "h3>")?.replaceAll("h1>", "h2>")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -3,10 +3,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { canvasPath as createBlobAnimation } from "blobs/v2/animate/index.js"
|
import blobsLib from "blobs/v2/animate"
|
||||||
import { ref, watchEffect } from "vue"
|
import { ref, watchEffect } from "vue"
|
||||||
import { useRafFn } from "@vueuse/core"
|
import { useRafFn } from "@vueuse/core"
|
||||||
|
|
||||||
|
const createBlobAnimation = blobsLib.canvasPath
|
||||||
|
|
||||||
function getComponentsOfHexColor(hexColorString) {
|
function getComponentsOfHexColor(hexColorString) {
|
||||||
return [
|
return [
|
||||||
Number.parseInt(hexColorString.slice(1, 3), 16),
|
Number.parseInt(hexColorString.slice(1, 3), 16),
|
||||||
|
|
|
@ -7,13 +7,12 @@
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { $fetch } from "ohmyfetch"
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-promise-executor-return
|
// eslint-disable-next-line no-promise-executor-return
|
||||||
const waitForAnimationFrame = () => new Promise(resolve => requestAnimationFrame(resolve))
|
const waitForAnimationFrame = () => new Promise(resolve => requestAnimationFrame(resolve))
|
||||||
|
|
||||||
const asyncSetup = async src => {
|
const asyncSetup = async src => {
|
||||||
const blob = await $fetch(src)
|
const response = await fetch(src)
|
||||||
|
const blob = await response.blob()
|
||||||
await waitForAnimationFrame() // makes sure the browser is idle
|
await waitForAnimationFrame() // makes sure the browser is idle
|
||||||
return {
|
return {
|
||||||
objectUrl: URL.createObjectURL(blob)
|
objectUrl: URL.createObjectURL(blob)
|
||||||
|
|
|
@ -12,14 +12,14 @@ export const photos: Photo[] = [
|
||||||
title: "Late afternoon",
|
title: "Late afternoon",
|
||||||
altText: "A red house in London",
|
altText: "A red house in London",
|
||||||
date: "2019",
|
date: "2019",
|
||||||
description: "Taken in London during a sunny afternoon.\nSeems to be 65 Curzon St."
|
description: "65 Curzon Street, Mayfair, London"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
file: "Martyrdom.webp",
|
file: "Martyrdom.webp",
|
||||||
title: "Martyrdom",
|
title: "Martyrdom",
|
||||||
altText: "A church on a vineyard",
|
altText: "A church on a vineyard",
|
||||||
date: "2019",
|
date: "2019",
|
||||||
description: "The Sankt-Laurentius church right by the Mosel river in Bremm (Germany)."
|
description: "The Sankt-Laurentius church by the Mosel river in Bremm (Germany)."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
file: "Heat.webp",
|
file: "Heat.webp",
|
||||||
|
|
|
@ -1,64 +0,0 @@
|
||||||
<template>
|
|
||||||
<NotFoundPage v-if="post === null" object-name="post" back-target="/blog"/>
|
|
||||||
<TopBarLayout v-else
|
|
||||||
title="Blog"
|
|
||||||
back-target="/blog"
|
|
||||||
no-set-title
|
|
||||||
>
|
|
||||||
<Head>
|
|
||||||
<title>{{ post.title }} — Moritz Ruth</title>
|
|
||||||
<meta name="keywords" :content="getKeywordsWithBase(post.tags).join(', ')">
|
|
||||||
</Head>
|
|
||||||
<article>
|
|
||||||
<h1 class="font-bold text-3xl sm:text-3xl sm:text-center font-special">
|
|
||||||
{{ post.title }}
|
|
||||||
</h1>
|
|
||||||
<XSpacer v="4"/>
|
|
||||||
<div class="flex justify-center -sm:flex-col -sm:space-y-1 -sm:pt-2 sm:space-x-3 text-sm sm:text-base">
|
|
||||||
<div>
|
|
||||||
Published at {{ post.published_at.slice(0, 10) }}
|
|
||||||
</div>
|
|
||||||
<div class="-sm:hidden">
|
|
||||||
|
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Reading time: {{ post.reading_time_minutes }} minute{{ post.reading_time_minutes === 1 ? "" : "s" }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<XSpacer v="8"/>
|
|
||||||
<Prose v-html="html"/>
|
|
||||||
</article>
|
|
||||||
</TopBarLayout>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style module>
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { useRoute } from "vue-router"
|
|
||||||
import { Head } from "@vueuse/head"
|
|
||||||
import TopBarLayout from "../../components/TopBarLayout.vue"
|
|
||||||
import { getPostBySlug } from "../../posts"
|
|
||||||
import Prose from "../../components/Prose.vue"
|
|
||||||
import XSpacer from "../../components/XSpacer.vue"
|
|
||||||
import NotFoundPage from "../../components/NotFoundPage.vue"
|
|
||||||
import { getKeywordsWithBase } from "../../data"
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "BlogPostPage",
|
|
||||||
components: { NotFoundPage, XSpacer, Prose, TopBarLayout, Head },
|
|
||||||
async setup() {
|
|
||||||
const route = useRoute()
|
|
||||||
|
|
||||||
const post = await getPostBySlug(route.params.slug as string)
|
|
||||||
|
|
||||||
return {
|
|
||||||
post,
|
|
||||||
// Yep, that's awful code
|
|
||||||
html: post?.body_html?.replaceAll("h2>", "h3>")?.replaceAll("h1>", "h2>"),
|
|
||||||
getKeywordsWithBase
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,65 +0,0 @@
|
||||||
<template>
|
|
||||||
<TopBarLayout title="Blog" back-target="/">
|
|
||||||
<div class="fixed top-0 left-0 bottom-0 right-0 flex justify-center items-center">
|
|
||||||
<BlurredBlobCanvas
|
|
||||||
:blur="50"
|
|
||||||
:size="400"
|
|
||||||
:randomness="400"
|
|
||||||
:minimum-duration="3000"
|
|
||||||
:duration-variation="1000"
|
|
||||||
:minimum-opacity="0.4"
|
|
||||||
:opacity-variation="0"
|
|
||||||
:colors="['#eb34cf', '#6577fc']"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-col space-y-8 max-w-120 mx-auto">
|
|
||||||
<router-link
|
|
||||||
v-for="post in posts"
|
|
||||||
:key="post.id"
|
|
||||||
:to="`/blog/${post.slug}`"
|
|
||||||
class="bg-light-300 bg-opacity-5 rounded-lg backdrop-blur-lg cursor-pointer hover:bg-opacity-10 focus-visible:bg-opacity-10 transform hover:scale-104
|
|
||||||
transition duration-200 p-5 sm:p-7 flex flex-col overflow-hidden"
|
|
||||||
>
|
|
||||||
<div class="font-bold text-xl">
|
|
||||||
{{ post.title }}
|
|
||||||
</div>
|
|
||||||
<XSpacer v="2"/>
|
|
||||||
<div class="text-lg">
|
|
||||||
{{ post.description }}
|
|
||||||
</div>
|
|
||||||
<XSpacer v="3"/>
|
|
||||||
<div class="font-bold text-sm flex justify-between">
|
|
||||||
<div>
|
|
||||||
Published at {{ new Date(post.published_at).toLocaleDateString() }}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
{{ post.reading_time_minutes }} minute{{ post.reading_time_minutes === 1 ? "" : "s" }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</router-link>
|
|
||||||
</div>
|
|
||||||
</TopBarLayout>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style module>
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import TopBarLayout from "../../components/TopBarLayout.vue"
|
|
||||||
import { getPosts } from "../../posts"
|
|
||||||
import XSpacer from "../../components/XSpacer.vue"
|
|
||||||
import BlurredBlobCanvas from "../../components/BlurredBlobCanvas.vue"
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "BlogIndexPage",
|
|
||||||
components: { BlurredBlobCanvas, XSpacer, TopBarLayout },
|
|
||||||
async setup() {
|
|
||||||
const posts = await getPosts()
|
|
||||||
|
|
||||||
return {
|
|
||||||
posts
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -21,10 +21,11 @@
|
||||||
<div class="text-lg sm:text-xl font-medium leading-8 pt-5">
|
<div class="text-lg sm:text-xl font-medium leading-8 pt-5">
|
||||||
<p>
|
<p>
|
||||||
I’m a freelance
|
I’m a freelance
|
||||||
software developer,
|
software developer
|
||||||
graphic design enthusiast and
|
from Europe.<br>
|
||||||
<router-link to="/photography" :class="$style.link">hobby photographer</router-link>
|
I also occasionally take
|
||||||
from Europe.
|
<router-link to="/photography" :class="$style.link">photos</router-link>
|
||||||
|
and make music.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<XSpacer v="10"/>
|
<XSpacer v="10"/>
|
||||||
|
@ -32,7 +33,7 @@
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
<div class="relative lg:pr-20 -lg:pt-20 pb-10 mt-0">
|
<div class="relative lg:pr-20 -lg:pt-20 pb-10 mt-0">
|
||||||
<nav class="absolute w-full pt-20 flex justify-center">
|
<nav class="absolute w-full pt-5 flex justify-center">
|
||||||
<BlurredBlobCanvas
|
<BlurredBlobCanvas
|
||||||
:blur="30"
|
:blur="30"
|
||||||
:size="300"
|
:size="300"
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
This legal notice (Impressum) is a requirement of the German Act for Telemedia Services (Telemediengesetz).
|
This legal notice (Impressum) is a requirement of the German Act for Telemedia Services (Telemediengesetz).
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
The declarations on this page only apply to this website (moritzruth.de) and all websites which reside under subdomains of moritzruth.de.
|
The declarations on this page only apply to this website (moritzruth.de) and all websites which reside under subdomains of moritzruth.de and deltaa.xyz.
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
|
|
21
src/posts.ts
21
src/posts.ts
|
@ -1,21 +0,0 @@
|
||||||
/* eslint-disable camelcase */
|
|
||||||
import { $fetch } from "ohmyfetch"
|
|
||||||
|
|
||||||
const USERNAME = "moritzruth"
|
|
||||||
|
|
||||||
export interface Post {
|
|
||||||
id: number
|
|
||||||
title: string
|
|
||||||
slug: string
|
|
||||||
description: string
|
|
||||||
published_at: string
|
|
||||||
reading_time_minutes: number
|
|
||||||
tags: string[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface FullPost extends Post {
|
|
||||||
body_html: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getPosts = () => $fetch<Post[]>(`https://dev.to/api/articles?username=${USERNAME}&per_page=1000`)
|
|
||||||
export const getPostBySlug = (slug: string) => $fetch<FullPost>(`https://dev.to/api/articles/${USERNAME}/${slug}`).catch(() => null)
|
|
3
src/vite-env.d.ts
vendored
3
src/vite-env.d.ts
vendored
|
@ -1,3 +0,0 @@
|
||||||
/// <reference types="vite-plugin-pages/client"/>
|
|
||||||
/// <reference types="unplugin-icons/types/vue"/>
|
|
||||||
/// <reference types="vite/client"/>
|
|
|
@ -1,16 +1,30 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"baseUrl": ".",
|
"declaration": false,
|
||||||
"module": "ESNext",
|
|
||||||
"target": "ES2021",
|
|
||||||
"lib": ["DOM", "ESNext"],
|
|
||||||
"strict": true,
|
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"skipLibCheck": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"lib": ["esnext", "dom"],
|
||||||
|
"module": "esnext",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
|
"allowJs": true,
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"strictNullChecks": true,
|
"importsNotUsedAsValues": "error",
|
||||||
"downlevelIteration": true,
|
"isolatedModules": true,
|
||||||
"forceConsistentCasingInFileNames": true
|
"rootDir": "src",
|
||||||
}
|
"skipLibCheck": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"strict": true,
|
||||||
|
"stripInternal": true,
|
||||||
|
"target": "esnext",
|
||||||
|
"types": [
|
||||||
|
"vite/client",
|
||||||
|
"unplugin-icons/types/vue",
|
||||||
|
"vite-plugin-pages/client"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*.ts",
|
||||||
|
"src/**/*.vue"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,17 +7,8 @@ import iconsPlugin from "unplugin-icons/vite"
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [
|
plugins: [
|
||||||
vuePlugin(),
|
vuePlugin(),
|
||||||
pagesPlugin({
|
pagesPlugin(),
|
||||||
syncIndex: false
|
|
||||||
}),
|
|
||||||
windicssPlugin(),
|
windicssPlugin(),
|
||||||
iconsPlugin()
|
iconsPlugin()
|
||||||
],
|
]
|
||||||
ssgOptions: {
|
|
||||||
formatting: "minify",
|
|
||||||
format: "cjs",
|
|
||||||
includedRoutes(routes) {
|
|
||||||
return routes.filter(route => !route.includes(":") && route !== "/blog")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
Loading…
Add table
Reference in a new issue