自定义404页面
自定义404页面
目录
[toc]
背景
逛掘金发现了一个很酷的 404 页面,于是想在自己的博客也搞一个,正好 VitePress也支持自定义 404 页面的内容,可以根据官方提供的not-found插槽去配置即可,在自定义的 docs/.vitepress/theme/index.ts
文件中去配置就行。
版权
警告
本着开源共享、共同学习的精神:
本文是在 《Hyde Blog》博主的《自定义404》文章 基础上增加了一些自己的实际操作记录和修改,内容依旧属于原作者所有。转载无需和我联系,但请注明文章来源。如果侵权之处,请联系博主进行删除,谢谢。
原始作者:《海拥》
环境
2025.4.14(已解决)
警告
次配置适用于Teek@1.0.2-2025.4.10
版本(其它版本可自行测试)。
提示
自己开源的 《vitepress-theme-teek-one-public》网站模板。
此模板是在《Young Kbt blog》大佬开源项目《vitepress-theme-teek 》基础上修改为自己的风格而成,感谢大佬开发得主题,大佬威武。❤️❤️
1、安装依赖
sh
pnpmadd-Dparallax-js
sh
npmadd-Dparallax-js
sh
yarnadd-Dparallax-js
sh
bunadd-Dparallax-js
2、新建组件
- 在
docs/.vitepress/theme/components
目录下新建NotFound.vue
文件,内容如下:
NotFound.vue文件内容:
vue
<scriptsetup>import{onMounted } from"vue";importParallax from"parallax-js";onMounted(() =>{constscene=document.getElementById("scene");if(scene) {newParallax(scene);}});constgoBack=() =>{window.history.back();};constgohome=() =>{window.location.href ="/";};constcontactMe=() =>{window.location.href ="mailto:2675263825@qq.com";};</script><template><div><!-- about --><divclass="about"><aclass="bg_links social portfolio"href="https:target="_blank"><spanclass="icon"></span></a><aclass="bg_links social dribbble"href="https:target="_blank"><spanclass="icon"></span></a><aclass="bg_links social linkedin"href="https:target="_blank"><spanclass="icon"></span></a><aclass="bg_links logo"></a></div><!-- end about --><nav><divclass="menu"><pclass="website_name"><ahref="https:</p><divclass="menu_links"><ahref="https:class="link">自定义404教程</a><ahref="https:class="link">源码</a><ahref="https:class="link">404关灯</a></div><divclass="menu_icon"><spanclass="icon"></span></div></div></nav><sectionclass="wrapper"><divclass="container"><divid="scene"class="scene"data-hover-only="false"><divclass="circle"data-depth="1.2"></div><divclass="one"data-depth="0.9"><divclass="content"><spanclass="piece"></span><spanclass="piece"></span><spanclass="piece"></span></div></div><divclass="two"data-depth="0.60"><divclass="content"><spanclass="piece"></span><spanclass="piece"></span><spanclass="piece"></span></div></div><divclass="three"data-depth="0.40"><divclass="content"><spanclass="piece"></span><spanclass="piece"></span><spanclass="piece"></span></div></div><pclass="p404"data-depth="0.50">404</p><pclass="p404"data-depth="0.10">404</p></div><divclass="text"><article><p>哎呀,您访问的页面不存在</p><p>可能页面地址已更改,请联系我~</p><divclass="button-group"><button@click="goBack">返回上一页</button><button@click="gohome">带我回家吧</button><button@click="contactMe">联系我</button></div></article></div></div></section></div></template><stylescoped>@importurl("https:.about{position:fixed;z-index:10;bottom:10px;right:80px;width:40px;height:40px;display:flex;justify-content:flex-end;align-items:flex-end;transition:all0.2sease;}.about.bg_links{width:40px;height:40px;border-radius:100%;display:flex;justify-content:center;align-items:center;background-color:rgba(0,0,0,0.2);border-radius:100%;backdrop-filter:blur(5px);position:absolute;}.about.logo{width:40px;height:40px;z-index:9;background-image:url(https:background-size:50%;background-repeat:no-repeat;background-position:10px7px;opacity:0.9;transition:all1s0.2sease;bottom:0;right:10px;}.about.social{opacity:0;right:0;bottom:0;}.about.social.icon{width:100%;height:100%;background-size:20px;background-repeat:no-repeat;background-position:center;background-color:transparent;display:flex;transition:all0.2sease,background-color 0.4sease;opacity:0;border-radius:100%;}.about.social.portfolio{transition:all0.8sease;}.about.social.portfolio.icon{background-image:url(https:}.about.social.dribbble{transition:all0.3sease;}.about.social.dribbble.icon{background-image:url(https:}.about.social.linkedin{transition:all0.8sease;}.about.social.linkedin.icon{background-image:url(https:}.about:hover{width:105px;height:105px;transition:all0.6scubic-bezier(0.64,0.01,0.07,1.65);}.about:hover.logo{opacity:1;transition:all0.6sease;}.about:hover.social{opacity:1;}.about:hover.social.icon{opacity:0.9;}.about:hover.social:hover{background-size:28px;}.about:hover.social:hover.icon{background-size:65%;opacity:1;}.about:hover.social.portfolio{right:0;bottom:calc(100%-40px);transition:all0.3s0scubic-bezier(0.64,0.01,0.07,1.65);}.about:hover.social.portfolio.icon:hover{background-color:#698fb7;}.about:hover.social.dribbble{bottom:45%;right:45%;transition:all0.3s0.15scubic-bezier(0.64,0.01,0.07,1.65);}.about:hover.social.dribbble.icon:hover{background-color:#ea4c89;}.about:hover.social.linkedin{bottom:0;right:calc(100%-40px);transition:all0.3s0.25scubic-bezier(0.64,0.01,0.07,1.65);}.about:hover.social.linkedin.icon:hover{background-color:#0077b5;}h1,h2,h3,h4,h5,h6,p,ul,li,button,a,i,input,body{margin:0;padding:0;list-style:none;border:0;-webkit-tap-highlight-color:transparent;text-decoration:none;color:inherit;}h1:focus,h2:focus,h3:focus,h4:focus,h5:focus,h6:focus,p:focus,ul:focus,li:focus,button:focus,a:focus,i:focus,input:focus,body:focus{outline:0;}body{margin:0;padding:0;height:auto;font-family:"Barlow",sans-serif;background:var(--bg-color);}.logo{position:fixed;z-index:5;bottom:10px;right:10px;width:40px;height:40px;border-radius:100%;display:flex;justify-content:center;align-items:center;background:rgba(0,0,0,0.1);border-radius:100%;backdrop-filter:blur(5px);}.logoimg{width:55%;height:55%;transform:translateY(-1px);opacity:0.8;}nav.menu{width:100%;height:80px;position:absolute;display:flex;align-items:center;justify-content:space-between;padding:05%;box-sizing:border-box;z-index:3;}nav.menu.website_name{color:var(--vp-c-brand-1);font-weight:600;font-size:20px;letter-spacing:1px;background:white;padding:4px8px;border-radius:2px;opacity:0.5;transition:all0.4sease;cursor:pointer;}nav.menu.website_name:hover{opacity:1;}nav.menu.menu_links{transition:all0.4sease;opacity:0.5;}nav.menu.menu_links:hover{opacity:1;}@mediascreenand(max-width:799px) {nav.menu.menu_links{display:none;}}nav.menu.menu_links.link{color:var(--vp-c-brand-1);text-transform:uppercase;font-weight:500;margin-right:50px;letter-spacing:2px;position:relative;transition:all0.3s0.2sease;}nav.menu.menu_links.link:last-child{margin-right:0;}nav.menu.menu_links.link:before{content:"";position:absolute;width:0px;height:4px;background:linear-gradient(90deg,#ffedc00%,#ff9d87100%);bottom:-10px;border-radius:4px;transition:all0.4scubic-bezier(0.82,0.02,0.13,1.26);left:100%;}nav.menu.menu_links.link:hover{opacity:1;color:#fb8a8a;}nav.menu.menu_links.link:hover:before{width:40px;left:0;}nav.menu.menu_icon{width:40px;height:40px;position:relative;display:none;justify-content:center;align-items:center;cursor:pointer;}@mediascreenand(max-width:799px) {nav.menu.menu_icon{display:flex;}}nav.menu.menu_icon.icon{width:24px;height:2px;background:white;position:absolute;}nav.menu.menu_icon.icon:before,nav.menu.menu_icon.icon:after{content:"";width:100%;height:100%;background:inherit;position:absolute;transition:all0.3scubic-bezier(0.49,0.04,0,1.55);}nav.menu.menu_icon.icon:before{transform:translateY(-8px);}nav.menu.menu_icon.icon:after{transform:translateY(8px);}nav.menu.menu_icon:hover.icon{background:#ffedc0;}nav.menu.menu_icon:hover.icon:before{transform:translateY(-10px);}nav.menu.menu_icon:hover.icon:after{transform:translateY(10px);}.wrapper{display:grid;grid-template-columns:1fr;justify-content:center;align-items:center;height:100vh;overflow-x:hidden;}.wrapper.container{margin:0auto;transition:all0.4sease;display:flex;justify-content:center;align-items:center;position:relative;}.wrapper.container.scene{position:absolute;width:100vw;height:100vh;vertical-align:middle;}.wrapper.container.one,.wrapper.container.two,.wrapper.container.three,.wrapper.container.circle,.wrapper.container.p404{width:60%;height:60%;top:20%!important;left:20%!important;min-width:400px;min-height:400px;}.wrapper.container.one.content,.wrapper.container.two.content,.wrapper.container.three.content,.wrapper.container.circle.content,.wrapper.container.p404.content{width:600px;height:600px;display:flex;justify-content:center;align-items:center;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);animation:content0.8scubic-bezier(1,0.06,0.25,1) backwards;}@keyframescontent{0%{width:0;}}.wrapper.container.one.content.piece,.wrapper.container.two.content.piece,.wrapper.container.three.content.piece,.wrapper.container.circle.content.piece,.wrapper.container.p404.content.piece{width:200px;height:80px;display:flex;position:absolute;border-radius:80px;z-index:1;animation:pieceLeft 8scubic-bezier(1,0.06,0.25,1) infiniteboth;}@keyframespieceLeft{50%{left:80%;width:10%;}}@keyframespieceRight{50%{right:80%;width:10%;}}@mediascreenand(max-width:799px) {.wrapper.container.one,.wrapper.container.two,.wrapper.container.three,.wrapper.container.circle,.wrapper.container.p404{width:90%;height:90%;top:5%!important;left:5%!important;min-width:280px;min-height:280px;}}@mediascreenand(max-height:660px) {.wrapper.container.one,.wrapper.container.two,.wrapper.container.three,.wrapper.container.circle,.wrapper.container.p404{min-width:280px;min-height:280px;width:60%;height:60%;top:20%!important;left:20%!important;}}.wrapper.container.text{width:60%;height:40%;min-width:400px;min-height:500px;position:absolute;margin:40px0;animation:text0.6s1.8seasebackwards;}@keyframestext{0%{opacity:0;transform:translateY(40px);}}@mediascreenand(max-width:799px) {.wrapper.container.text{min-height:400px;height:80%;}}.wrapper.container.textarticle{width:400px;position:absolute;bottom:0;z-index:4;display:flex;flex-direction:column;justify-content:center;align-items:center;text-align:center;bottom:0;left:50%;transform:translateX(-50%);}@mediascreenand(max-width:799px) {.wrapper.container.textarticle{width:100%;}}.wrapper.container.textarticlep{color:white;font-size:18px;letter-spacing:0.6px;margin-bottom:40px;text-shadow:6px6px10px#32243e;}.wrapper.container.textarticlebutton{height:40px;padding:030px;border-radius:50px;cursor:pointer;box-shadow:0px15px20pxrgba(54,24,79,0.5);z-index:3;color:var(--vp-c-brand-1);background-color:white;text-transform:uppercase;font-weight:600;font-size:12px;transition:all0.3sease;}.wrapper.container.textarticlebutton:hover{box-shadow:0px10px10px-10pxrgba(54,24,79,0.5);transform:translateY(5px);background:#fb8a8a;color:white;}.wrapper.container.p404{font-size:200px;font-weight:700;letter-spacing:4px;color:white;display:flex!important;justify-content:center;align-items:center;position:absolute;z-index:2;animation:anime404 0.6scubic-bezier(0.3,0.8,1,1.05) both;animation-delay:1.2s;}@mediascreenand(max-width:799px) {.wrapper.container.p404{font-size:100px;}}@keyframesanime404{0%{opacity:0;transform:scale(10) skew(20deg,20deg);}}.wrapper.container.p404:nth-of-type(2) {color:#36184f;z-index:1;animation-delay:1s;filter:blur(10px);opacity:0.8;}.wrapper.container.circle{position:absolute;}.wrapper.container.circle:before{content:"";position:absolute;width:800px;height:800px;background-color:rgba(54,24,79,0.2);border-radius:100%;top:50%;left:50%;transform:translate(-50%,-50%);box-shadow:inset5px20px40pxrgba(54,24,79,0.25),inset5px0px5pxrgba(50,36,62,0.3),inset5px5px20pxrgba(50,36,62,0.25),2px2px5pxrgba(255,255,255,0.2);animation:circle0.8scubic-bezier(1,0.06,0.25,1) backwards;}@keyframescircle{0%{width:0;height:0;}}@mediascreenand(max-width:799px) {.wrapper.container.circle:before{width:400px;height:400px;}}.wrapper.container.one.content:before{content:"";position:absolute;width:600px;height:600px;background-color:rgba(54,24,79,0.3);border-radius:100%;box-shadow:inset5px20px40pxrgba(54,24,79,0.25),inset5px0px5pxrgba(50,36,62,0.3),inset5px5px20pxrgba(50,36,62,0.25),2px2px5pxrgba(255,255,255,0.2);animation:circle0.8s0.4scubic-bezier(1,0.06,0.25,1) backwards;}@mediascreenand(max-width:799px) {.wrapper.container.one.content:before{width:300px;height:300px;}}.wrapper.container.one.content.piece{background:linear-gradient(90deg,#8077ea13.7%,#eb73ff94.65%);}.wrapper.container.one.content.piece:nth-child(1) {right:15%;top:18%;height:30px;width:120px;animation-delay:0.5s;animation-name:pieceRight;}.wrapper.container.one.content.piece:nth-child(2) {left:15%;top:45%;width:150px;height:50px;animation-delay:1s;animation-name:pieceLeft;}.wrapper.container.one.content.piece:nth-child(3) {left:10%;top:75%;height:20px;width:70px;animation-delay:1.5s;animation-name:pieceLeft;}.wrapper.container.two.content.piece{background:linear-gradient(90deg,#ffedc00%,#ff9d87100%);}.wrapper.container.two.content.piece:nth-child(1) {left:0%;top:25%;height:40px;width:120px;animation-delay:2s;animation-name:pieceLeft;}.wrapper.container.two.content.piece:nth-child(2) {right:15%;top:35%;width:180px;height:50px;animation-delay:2.5s;animation-name:pieceRight;}.wrapper.container.two.content.piece:nth-child(3) {right:10%;top:80%;height:20px;width:160px;animation-delay:3s;animation-name:pieceRight;}.wrapper.container.three.content.piece{background:#fb8a8a;}.wrapper.container.three.content.piece:nth-child(1) {left:25%;top:35%;height:20px;width:80px;animation-name:pieceLeft;animation-delay:3.5s;}.wrapper.container.three.content.piece:nth-child(2) {right:10%;top:55%;width:140px;height:40px;animation-name:pieceRight;animation-delay:4s;}.wrapper.container.three.content.piece:nth-child(3) {left:40%;top:68%;height:20px;width:80px;animation-name:pieceLeft;animation-delay:4.5s;}.button-group{display:flex;gap:20px;}</style>
3、注册组件
- 在
docs/.vitepress/theme/index.ts
中注册组件
ts
import{h } from"vue";importDefaultTheme from"vitepress/theme";importNotFound from"./components/NotFound.vue";exportdefault{Layout:() =>{constprops={};const{frontmatter} =useData();if(frontmatter.value?.layoutClass) {props.class =frontmatter.value.layoutClass;}returnh(DefaultTheme.Layout,props,{"doc-after":() =>h(siteFooter),"not-found":() =>h(NotFound),});},};
自己实际docs/.vitepress/theme/index.ts
配置内容:
ts
importTeek,{teekConfigSymbol } from"vitepress-theme-teek";importTeekLayoutProvider from"./components/TeekLayoutProvider.vue";import"vitepress-theme-teek/index.css";importNoticeContent from"./components/NoticeContent.vue";importBannerImgArrow from"./components/BannerImgArrow.vue";import{defineComponent,h,nextTick,provide,watch } from"vue";import{useData,useRoute } from"vitepress";import{artalkSymbol,giscusSymbol,walineSymbol } from"vitepress-theme-teek";import"vitepress-theme-teek/vp-plus/code-block-mobile.scss";import"vitepress-theme-teek/vp-plus/sidebar.scss";import"vitepress-theme-teek/vp-plus/nav.scss";import"vitepress-theme-teek/vp-plus/nav-blur.scss";import"vitepress-theme-teek/vp-plus/aside.scss";import"vitepress-theme-teek/vp-plus/doc-h1-gradient.scss";import"vitepress-theme-teek/vp-plus/mark.scss";import"vitepress-theme-teek/vp-plus/container.scss";import"vitepress-theme-teek/vp-plus/container-left.scss";import"vitepress-theme-teek/vp-plus/blockquote.scss";import"vitepress-theme-teek/vp-plus/index-rainbow.scss";import"vitepress-theme-teek/tk-plus/banner-desc-gradient.scss";import"vitepress-theme-teek/tk-plus/banner-full-img-scale.scss";import"./styles/code-bg.scss";import"./styles/index.scss";import{useFooterRuntime } from"./helper/useFooterRuntime";importconfetti from"./components/Confetti.vue";import"vitepress-markdown-timeline/dist/theme/index.css";import"virtual:group-icons.css";importNotFound from"./components/NotFound.vue";import{init } from"@waline/client";import"@waline/client/style";importGiscus from"@giscus/vue";import"artalk/Artalk.css";importArtalk from"artalk";exportdefault{extends:Teek,enhanceApp({app}) {app.component("confetti",confetti);},Layout:defineComponent({name:"LayoutProvider",setup() {const{frontmatter,isDark,page} =useData();const{start,stop} =useFooterRuntime();constroute=useRoute();provide(walineSymbol,(options,el) =>init({serverURL:options.serverURL!,dark:options.dark,el }));provide(giscusSymbol,() =>Giscus);provide(artalkSymbol,(options,el) =>Artalk.init({el,darkMode:isDark.value,pageKey:route.path,pageTitle:page.value.title,server:options.server,site:options.site,}));watch(frontmatter,() =>{nextTick(() =>{if(frontmatter.value.layout ==="home") start();elsestop();});},{immediate:true});return() =>h(TeekLayoutProvider,null,{"teek-notice-content":() =>h(NoticeContent),"teek-home-banner-feature-after":() =>h(BannerImgArrow),"not-found":() =>h(NotFound),});},}),};
4、测试
运行项目,随便输入一个不存在的url:
404.vue 页面
xml
<template><divclass="not-found"><h1>404</h1><p>哎呀,您访问的页面不存在!</p><ahref="/404.html"target="_self">返回首页</a></div></template>
这样就可以自定义VitePress的404页面内容了。