_app.tsx 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import App, { AppContext } from "next/app";
  2. import { StoreProvider } from "easy-peasy";
  3. import getConfig from "next/config";
  4. import Router from "next/router";
  5. import decode from "jwt-decode";
  6. import cookie from "js-cookie";
  7. import Head from "next/head";
  8. import React from "react";
  9. import { initializeStore } from "../store";
  10. import { TokenPayload } from "../types";
  11. const { publicRuntimeConfig } = getConfig();
  12. // TODO: types
  13. class MyApp extends App<any> {
  14. static async getInitialProps({ Component, ctx }: AppContext) {
  15. const store = initializeStore();
  16. ctx.store = store;
  17. let pageProps = {};
  18. if (Component.getInitialProps) {
  19. pageProps = await Component.getInitialProps(ctx);
  20. }
  21. const token =
  22. ctx.req && (ctx.req as any).cookies && (ctx.req as any).cookies.token;
  23. const tokenPayload: TokenPayload = token ? decode(token) : null;
  24. if (tokenPayload) {
  25. store.dispatch.auth.add(tokenPayload);
  26. }
  27. return { pageProps, tokenPayload, initialState: store.getState() };
  28. }
  29. store: ReturnType<typeof initializeStore>;
  30. constructor(props) {
  31. super(props);
  32. this.store = initializeStore(props.initialState);
  33. }
  34. componentDidMount() {
  35. const { loading, auth } = this.store.dispatch;
  36. const token = cookie.get("token");
  37. const isVerifyEmailPage =
  38. typeof window !== "undefined" &&
  39. window.location.pathname.includes("verify-email");
  40. if (token && !isVerifyEmailPage) {
  41. auth.renew().catch(() => {
  42. auth.logout();
  43. });
  44. }
  45. Router.events.on("routeChangeStart", () => loading.show());
  46. Router.events.on("routeChangeComplete", () => {
  47. loading.hide();
  48. });
  49. Router.events.on("routeChangeError", () => loading.hide());
  50. }
  51. render() {
  52. const { Component, pageProps } = this.props;
  53. return (
  54. <>
  55. <Head>
  56. <title>
  57. {publicRuntimeConfig.SITE_NAME} | Modern Open Source URL shortener.
  58. </title>
  59. </Head>
  60. <StoreProvider store={this.store}>
  61. <Component {...pageProps} />
  62. </StoreProvider>
  63. </>
  64. );
  65. }
  66. }
  67. export default MyApp;