Skip to content

Commit 23af964

Browse files
feat: 404 page for categories and posts
1 parent 97c671b commit 23af964

File tree

5 files changed

+56
-9
lines changed

5 files changed

+56
-9
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
33
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
44

5+
#### [1.2.0] - 2020-10-09
6+
7+
##### Added
8+
- Redirect to 404 page if post or category not found
9+
10+
#### [1.1.1] - 2020-10-09
11+
12+
##### Added
13+
- Removed moment.js - replaced with day.js
14+
515
#### [1.1.0] - 2020-08-20
616

717
##### Added

helpers/index.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { AsyncDataLoader } from "@vue-storefront/core/lib/async-data-loader"
2+
3+
export async function getContext(ctx) {
4+
if (ctx) {
5+
return ctx
6+
}
7+
8+
return new Promise(resolve => {
9+
AsyncDataLoader.push({
10+
execute: async (app) => {
11+
resolve(app.context)
12+
}
13+
})
14+
})
15+
}

pages/BlogCategory.vue

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ import { Logger } from '@vue-storefront/core/lib/logger'
102102
import { isServer } from '@vue-storefront/core/helpers'
103103
import { htmlDecode } from '@vue-storefront/core/filters/html-decode'
104104
import { mapGetters } from 'vuex'
105+
import { getContext } from '../helpers'
105106
106107
// Components
107108
import Breadcrumbs from 'theme/components/core/Breadcrumbs'
@@ -110,7 +111,7 @@ import BlogListing from '../components/BlogListing'
110111
111112
const POSTS_PER_PAGE = 10
112113
113-
const composeInitialPageState = async (store, route, forceLoad = false) => {
114+
const composeInitialPageState = async (store, route, context = null) => {
114115
try {
115116
await store.dispatch('aheadworks-blog/loadCategories', {
116117
size: 200
@@ -120,6 +121,12 @@ const composeInitialPageState = async (store, route, forceLoad = false) => {
120121
121122
if (route.params.slug) {
122123
currentCategory = await store.getters['aheadworks-blog/getCurrentCategory']
124+
125+
if (!currentCategory && isServer) {
126+
const ctx = await getContext(context)
127+
ctx.server.response.redirect('/page-not-found', 302)
128+
}
129+
123130
await store.dispatch('aheadworks-blog/loadCategoryPosts', {
124131
category: currentCategory,
125132
perPage: POSTS_PER_PAGE
@@ -199,14 +206,14 @@ export default {
199206
}
200207
},
201208
async asyncData ({ store, route, context }) { // this is for SSR purposes to prefetch data - and it's always executed before parent component methods
202-
await composeInitialPageState(store, route)
209+
await composeInitialPageState(store, route, context)
203210
},
204211
async beforeRouteEnter (to, from, next) {
205212
if (isServer) next() // SSR no need to invoke SW caching here
206213
else if (!from.name) { // SSR but client side invocation, we need to cache products and invoke requests from asyncData for offline support
207214
next(async vm => {
208215
vm.loading = true
209-
await composeInitialPageState(vm.$store, to, true)
216+
await composeInitialPageState(vm.$store, to)
210217
vm.loading = false
211218
})
212219
} else {

pages/BlogPost.vue

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,20 +107,26 @@ import config from 'config'
107107
import { htmlDecode } from '@vue-storefront/core/filters/html-decode'
108108
import { mapGetters } from 'vuex'
109109
import dayjs from 'dayjs'
110+
import { getContext } from '../helpers'
110111
111-
const composeInitialPageState = async (store, route, force = false) => {
112+
const composeInitialPageState = async (store, route, context = null) => {
112113
try {
113114
await store.dispatch('aheadworks-blog/loadCategories', {
114115
size: 200
115116
})
116117
117118
const cached = store.getters['aheadworks-blog/getCurrentPost']
118119
if (!cached && route.params.slug) {
119-
await store.dispatch('aheadworks-blog/loadPost', {
120+
const post = await store.dispatch('aheadworks-blog/loadPost', {
120121
filters: {
121122
url_key: route.params.slug
122123
}
123124
})
125+
126+
if (!post && isServer) {
127+
const ctx = await getContext(context)
128+
ctx.server.response.redirect('/page-not-found', 302)
129+
}
124130
}
125131
126132
await store.dispatch('aheadworks-blog/loadRecentPosts')
@@ -176,14 +182,14 @@ export default {
176182
}
177183
},
178184
async asyncData ({ store, route, context }) { // this is for SSR purposes to prefetch data - and it's always executed before parent component methods
179-
await composeInitialPageState(store, route)
185+
await composeInitialPageState(store, route, context)
180186
},
181187
async beforeRouteEnter (to, from, next) {
182188
if (isServer) next() // SSR no need to invoke SW caching here
183189
else if (!from.name) { // SSR but client side invocation, we need to cache products and invoke requests from asyncData for offline support
184190
next(async vm => {
185191
vm.loading = true
186-
await composeInitialPageState(vm.$store, to, true)
192+
await composeInitialPageState(vm.$store, to)
187193
vm.loading = false
188194
})
189195
} else {

state/actions.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import RootState from '@vue-storefront/core/types/RootState'
33
import { BlogCategory, BlogState, BlogCategorySearchOptions, BlogPost, BlogPostSearchOptions } from '../types'
44
import { BlogCategoryService, BlogPostService } from '../data-resolver'
55
import { BLOG_ADD_CATEGORY, BLOG_SET_SEARCH_POSTS_STATS, BLOG_SET_CATEGORY_POSTS, BLOG_SET_RECENT_POSTS, BLOG_ADD_CATEGORIES, BLOG_ADD_POST } from './mutation-types'
6+
import { Logger } from '@vue-storefront/core/lib/logger'
67

78
const actions: ActionTree<BlogState, RootState> = {
89
async loadCategories ({ commit }, categorySearchOptions: BlogCategorySearchOptions): Promise<BlogCategory[]> {
@@ -24,7 +25,11 @@ const actions: ActionTree<BlogState, RootState> = {
2425
const { items } = await BlogCategoryService.getBlogCategories(categorySearchOptions)
2526
const category: BlogCategory = items && items.length ? items[0] : null
2627

27-
commit(BLOG_ADD_CATEGORY, category)
28+
if (category) {
29+
commit(BLOG_ADD_CATEGORY, category)
30+
} else {
31+
Logger.warn('Blog category not found', 'aheadworks-blog')()
32+
}
2833

2934
return category
3035
},
@@ -40,7 +45,11 @@ const actions: ActionTree<BlogState, RootState> = {
4045
const { items } = await BlogPostService.getBlogPosts(postSearchOptions)
4146
const post: BlogPost = items && items.length ? items[0] : null
4247

43-
commit(BLOG_ADD_POST, post)
48+
if (post) {
49+
commit(BLOG_ADD_POST, post)
50+
} else {
51+
Logger.warn('Blog post not found', 'aheadworks-blog')()
52+
}
4453

4554
return post
4655
},

0 commit comments

Comments
 (0)