| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- import { SWRConfig } from "swr";
- import Script from "next/script";
- import type { NextPage } from "next";
- import { useRouter } from "next/router";
- import type { AppProps } from "next/app";
- import App, { AppContext } from "next/app";
- import { ReactElement, ReactNode, useEffect, useMemo } from "react";
- import { get } from "libs/http";
- import { pageview } from "libs/gtag";
- import { Context } from "libs/context";
- import { GA_TRACKING_ID } from "libs/config";
- import Layout from "components/common/Layout";
- import getSiteConfig, { SiteConfig } from "libs/getSiteConfig";
- import "styles/globals.scss";
- import { SeoHead, SeoHeadConfig } from "components/SeoHead";
- export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
- getLayout?: (page: ReactElement) => ReactNode;
- };
- type AppPropsWithLayout = AppProps & {
- Component: NextPageWithLayout;
- pageProps: {
- fallback?: Docs;
- siteConfig: SiteConfig;
- };
- };
- const MyApp = ({ Component, pageProps }: AppPropsWithLayout) => {
- const { fallback, genre, siteConfig, ...otherProps } = pageProps;
- const router = useRouter();
- const seoConfig: SeoHeadConfig = useMemo(() => {
- return {
- title: siteConfig.title,
- description: siteConfig.description,
- keywords: siteConfig.keywords,
- url: `https://${siteConfig.host}`,
- canonical: `https://${siteConfig.host}`,
- jsonLd: JSON.stringify(siteConfig.jsonLd),
- siteName: siteConfig.siteName,
- img: siteConfig.touchIcon,
- };
- }, [
- siteConfig.description,
- siteConfig.host,
- siteConfig.jsonLd,
- siteConfig.keywords,
- siteConfig.siteName,
- siteConfig.title,
- siteConfig.touchIcon,
- ]);
- useEffect(() => {
- const handleRouteChange = (url: string) => {
- pageview(url);
- };
- router.events.on("routeChangeComplete", handleRouteChange);
- router.events.on("hashChangeComplete", handleRouteChange);
- return () => {
- router.events.off("routeChangeComplete", handleRouteChange);
- router.events.off("hashChangeComplete", handleRouteChange);
- };
- }, [router.events]);
- return (
- <>
- <SeoHead seoConfig={seoConfig}>
- <meta charSet="utf-8" />
- <meta httpEquiv="X-UA-Compatible" content="IE=edge" />
- <meta
- name="viewport"
- content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"
- />
- <link rel="manifest" href="/manifest.json" />
- <link rel="icon" href="/logo.svg" type="image/svg+xml" />
- <link rel="icon" href="/favicon.ico" type="image/x-icon" />
- <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
- <link rel="mask-icon" href="/logo.svg" color="#000000" />
- <link
- href="/favicon-16x16.png"
- rel="icon"
- type="image/png"
- sizes="16x16"
- />
- <link
- href="/favicon-32x32.png"
- rel="icon"
- type="image/png"
- sizes="32x32"
- />
- <link rel="apple-touch-icon" href={siteConfig.touchIcon} />
- <meta name="apple-mobile-web-app-title" content={siteConfig.siteName} />
- <meta name="application-name" content={siteConfig.siteName} />
- <meta
- name="theme-color"
- content="#ffffff"
- media="(prefers-color-scheme: light)"
- data-react-helmet="true"
- />
- <meta
- name="theme-color"
- content="#111827"
- media="(prefers-color-scheme: dark)"
- data-react-helmet="true"
- />
- <meta data-rh="true" name="theme-color" content="#111827" />
- <meta name="msapplication-TileColor" content="#5b5b5b" />
- <meta name="msapplication-TileImage" content={siteConfig.touchIcon} />
- <meta name="msapplication-tooltip" content={siteConfig.title} />
- </SeoHead>
- <Script
- strategy="afterInteractive"
- src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`}
- />
- <Context.Provider value={{ genre, siteConfig }}>
- <SWRConfig value={{ fallback, revalidateIfStale: false }}>
- {Component.getLayout && !pageProps.statusCode ? (
- Component.getLayout(<Component {...otherProps} />)
- ) : (
- <Layout>
- <Component {...otherProps} />
- </Layout>
- )}
- </SWRConfig>
- </Context.Provider>
- </>
- );
- };
- MyApp.getInitialProps = async function (context: AppContext) {
- App.getInitialProps(context);
- const { data } = await get<GenreItem[]>("/api/genre/list");
- return {
- pageProps: {
- genre: data,
- fallback: { "/api/genre/list": data },
- siteConfig: getSiteConfig(context.ctx.req?.headers.host),
- },
- };
- };
- export default MyApp;
|