parent
a8898677a9
commit
d37dd134b5
|
@ -76,7 +76,8 @@ const pagesMap: Record<keyof typeof ROUTES, Component<PageProps>> = {
|
||||||
thanks: ThanksPage,
|
thanks: ThanksPage,
|
||||||
profileSettings: ProfileSettingsPage,
|
profileSettings: ProfileSettingsPage,
|
||||||
profileSecurity: ProfileSecurityPage,
|
profileSecurity: ProfileSecurityPage,
|
||||||
profileSubscriptions: ProfileSubscriptionsPage
|
profileSubscriptions: ProfileSubscriptionsPage,
|
||||||
|
fourOuFour: FourOuFourPage
|
||||||
}
|
}
|
||||||
|
|
||||||
export const App = (props: PageProps) => {
|
export const App = (props: PageProps) => {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { capitalize, formatDate } from '../../utils'
|
import { formatDate } from '../../utils'
|
||||||
import { Icon } from '../_shared/Icon'
|
import { Icon } from '../_shared/Icon'
|
||||||
import { AuthorCard } from '../Author/AuthorCard'
|
import { AuthorCard } from '../Author/AuthorCard'
|
||||||
import { AudioPlayer } from './AudioPlayer'
|
import { AudioPlayer } from './AudioPlayer'
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
import type { PageContext } from '../renderer/types'
|
import type { PageContext } from '../renderer/types'
|
||||||
import type { PageProps } from './types'
|
import type { PageProps } from './types'
|
||||||
import { apiClient } from '../utils/apiClient'
|
import { apiClient } from '../utils/apiClient'
|
||||||
|
import { RenderErrorPage } from 'vite-plugin-ssr/RenderErrorPage'
|
||||||
|
|
||||||
export const onBeforeRender = async (pageContext: PageContext) => {
|
export const onBeforeRender = async (pageContext: PageContext) => {
|
||||||
const { slug } = pageContext.routeParams
|
const { slug } = pageContext.routeParams
|
||||||
const article = await apiClient.getShoutBySlug(slug)
|
const article = await apiClient.getShoutBySlug(slug)
|
||||||
|
|
||||||
|
if (!article) {
|
||||||
|
throw RenderErrorPage({ pageContext: {} })
|
||||||
|
}
|
||||||
|
|
||||||
const pageProps: PageProps = { article }
|
const pageProps: PageProps = { article }
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
4
src/pages/fourOuFour.page.route.ts
Normal file
4
src/pages/fourOuFour.page.route.ts
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
import { ROUTES } from '../stores/router'
|
||||||
|
import { getServerRoute } from '../utils/getServerRoute'
|
||||||
|
|
||||||
|
export default getServerRoute(ROUTES.fourOuFour)
|
|
@ -8,11 +8,20 @@ import HttpApi from 'i18next-http-backend'
|
||||||
import * as Sentry from '@sentry/browser'
|
import * as Sentry from '@sentry/browser'
|
||||||
import { SENTRY_DSN } from '../utils/config'
|
import { SENTRY_DSN } from '../utils/config'
|
||||||
import { resolveHydrationPromise } from '../utils/hydrationPromise'
|
import { resolveHydrationPromise } from '../utils/hydrationPromise'
|
||||||
|
import { initRouter } from '../stores/router'
|
||||||
|
|
||||||
let layoutReady = false
|
let layoutReady = false
|
||||||
|
|
||||||
export const render = async (pageContext: PageContextBuiltInClientWithClientRouting & PageContext) => {
|
export const render = async (pageContext: PageContextBuiltInClientWithClientRouting & PageContext) => {
|
||||||
const { lng, pageProps } = pageContext
|
const { lng, pageProps, is404 } = pageContext
|
||||||
|
|
||||||
|
if (is404) {
|
||||||
|
initRouter('/404')
|
||||||
|
} else {
|
||||||
|
const { pathname, search } = window.location
|
||||||
|
const searchParams = Object.fromEntries(new URLSearchParams(search))
|
||||||
|
initRouter(pathname, searchParams)
|
||||||
|
}
|
||||||
|
|
||||||
if (SENTRY_DSN) {
|
if (SENTRY_DSN) {
|
||||||
Sentry.init({
|
Sentry.init({
|
||||||
|
|
|
@ -9,7 +9,7 @@ import ru from '../../public/locales/ru/translation.json'
|
||||||
import en from '../../public/locales/en/translation.json'
|
import en from '../../public/locales/en/translation.json'
|
||||||
import type { Language } from '../context/localize'
|
import type { Language } from '../context/localize'
|
||||||
|
|
||||||
export const passToClient = ['pageProps', 'lng', 'documentProps']
|
export const passToClient = ['pageProps', 'lng', 'documentProps', 'is404']
|
||||||
|
|
||||||
const metaTags = []
|
const metaTags = []
|
||||||
|
|
||||||
|
@ -47,7 +47,11 @@ export const render = async (pageContext: PageContext) => {
|
||||||
await changeLanguage(lng)
|
await changeLanguage(lng)
|
||||||
}
|
}
|
||||||
|
|
||||||
initRouter(pageContext.urlParsed.pathname, pageContext.urlParsed.search)
|
if (pageContext.is404) {
|
||||||
|
initRouter('/404')
|
||||||
|
} else {
|
||||||
|
initRouter(pageContext.urlParsed.pathname, pageContext.urlParsed.search)
|
||||||
|
}
|
||||||
|
|
||||||
pageContext.lng = lng
|
pageContext.lng = lng
|
||||||
|
|
||||||
|
|
4
src/renderer/_error.page.ts
Normal file
4
src/renderer/_error.page.ts
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
// this file is required by vite-plugin-ssr to show something after an error occurred
|
||||||
|
// it's empty because error handling logic lives in _default.page.server.tsx and _default.page.client.tsx
|
||||||
|
|
||||||
|
// eslint-disable-next-line unicorn/no-empty-file
|
|
@ -1,4 +1,4 @@
|
||||||
import type { PageContextBuiltIn } from 'vite-plugin-ssr'
|
import type { PageContextBuiltIn } from 'vite-plugin-ssr/types'
|
||||||
import type { PageProps } from '../pages/types'
|
import type { PageProps } from '../pages/types'
|
||||||
import type { Component } from 'solid-js'
|
import type { Component } from 'solid-js'
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@ export const ROUTES = {
|
||||||
feedBookmarks: '/feed/bookmarks',
|
feedBookmarks: '/feed/bookmarks',
|
||||||
feedCollaborations: '/feed/collaborations',
|
feedCollaborations: '/feed/collaborations',
|
||||||
search: '/search/:q?',
|
search: '/search/:q?',
|
||||||
article: '/:slug',
|
|
||||||
dogma: '/about/dogma',
|
dogma: '/about/dogma',
|
||||||
discussionRules: '/about/discussion-rules',
|
discussionRules: '/about/discussion-rules',
|
||||||
guide: '/about/guide',
|
guide: '/about/guide',
|
||||||
|
@ -37,7 +36,9 @@ export const ROUTES = {
|
||||||
expo: '/expo/:layout',
|
expo: '/expo/:layout',
|
||||||
profileSettings: '/profile/settings',
|
profileSettings: '/profile/settings',
|
||||||
profileSecurity: '/profile/security',
|
profileSecurity: '/profile/security',
|
||||||
profileSubscriptions: '/profile/subscriptions'
|
profileSubscriptions: '/profile/subscriptions',
|
||||||
|
fourOuFour: '/404',
|
||||||
|
article: '/:slug'
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
const searchParamsStore = createSearchParams()
|
const searchParamsStore = createSearchParams()
|
||||||
|
@ -117,7 +118,7 @@ const handleClientRouteLinkClick = async (event) => {
|
||||||
scrollToHash(url.hash)
|
scrollToHash(url.hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const initRouter = (pathname: string, search: Record<string, string>) => {
|
export const initRouter = (pathname: string, search?: Record<string, string>) => {
|
||||||
routerStore.open(pathname)
|
routerStore.open(pathname)
|
||||||
const params = Object.fromEntries(new URLSearchParams(search))
|
const params = Object.fromEntries(new URLSearchParams(search))
|
||||||
searchParamsStore.open(params)
|
searchParamsStore.open(params)
|
||||||
|
@ -127,12 +128,6 @@ export const initRouter = (pathname: string, search: Record<string, string>) =>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isServer) {
|
|
||||||
const { pathname, search } = window.location
|
|
||||||
const searchParams = Object.fromEntries(new URLSearchParams(search))
|
|
||||||
initRouter(pathname, searchParams)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useRouter = <TSearchParams extends Record<string, string> = Record<string, string>>() => {
|
export const useRouter = <TSearchParams extends Record<string, string> = Record<string, string>>() => {
|
||||||
const page = useStore(routerStore)
|
const page = useStore(routerStore)
|
||||||
const searchParams = useStore(searchParamsStore) as unknown as Accessor<TSearchParams>
|
const searchParams = useStore(searchParamsStore) as unknown as Accessor<TSearchParams>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user