Skip to content

Commit

Permalink
feat: app router
Browse files Browse the repository at this point in the history
  • Loading branch information
denkristoffer committed Sep 4, 2024
1 parent 7b1cf0f commit 4656dd7
Show file tree
Hide file tree
Showing 57 changed files with 4,919 additions and 2,934 deletions.
5 changes: 4 additions & 1 deletion codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import { CodegenConfig } from '@graphql-codegen/cli';

const endpointOverride = process.env.CONTENTFUL_GRAPHQL_ENDPOINT;
const productionEndpoint = 'https://graphql.contentful.com/content/v1/spaces';
export const endpoint = `${endpointOverride || productionEndpoint}/${process.env.CONTENTFUL_SPACE_ID}`;
export const endpoint = `${endpointOverride || productionEndpoint}/${
process.env.CONTENTFUL_SPACE_ID
}/environments/${process.env.CONTENTFUL_SPACE_ENVIRONMENT || 'master'}`;

export const config: CodegenConfig = {
overwrite: true,
ignoreNoDocuments: true,
Expand Down
13 changes: 0 additions & 13 deletions config/plugins.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,6 @@
const withBundleAnalyzer = require('@next/bundle-analyzer');
const withPWA = require('next-pwa');

module.exports = [
[
withPWA,
{
pwa: {
disable: process.env.NODE_ENV !== 'production',
dest: `public`,
register: false,
swSrc: './service-worker.js',
publicExcludes: ['!favicon/**/*'],
},
},
],
[
withBundleAnalyzer,
{
Expand Down
10 changes: 0 additions & 10 deletions next-i18next.config.js

This file was deleted.

16 changes: 10 additions & 6 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ const nextComposePlugins = require('next-compose-plugins');

const headers = require('./config/headers');
const plugins = require('./config/plugins');
const { i18n } = require('./next-i18next.config.js');

/**
* https://github.com/cyrilwanner/next-compose-plugins/issues/59
Expand All @@ -15,7 +14,6 @@ const { withPlugins } = nextComposePlugins.extend(() => ({}));
* documentation: https://nextjs.org/docs/api-reference/next.config.js/introduction
*/
module.exports = withPlugins(plugins, {
i18n,
/**
* add the environment variables you would like exposed to the client here
* documentation: https://nextjs.org/docs/api-reference/next.config.js/environment-variables
Expand All @@ -42,7 +40,6 @@ module.exports = withPlugins(plugins, {
// swcMinify: true,

poweredByHeader: false,
reactStrictMode: false,
compress: true,

/**
Expand All @@ -57,11 +54,18 @@ module.exports = withPlugins(plugins, {
* Settings are the defaults
*/
images: {
domains: ['images.ctfassets.net','images.eu.ctfassets.net'],
remotePatterns: [
{
protocol: 'https',
hostname: 'images.ctfassets.net',
},
{
protocol: 'https',
hostname: 'images.eu.ctfassets.net',
},
],
},

pageExtensions: ['page.tsx', 'page.ts', 'page.jsx', 'page.js'],

webpack(config) {
config.module.rules.push({
test: /\.svg$/,
Expand Down
33 changes: 17 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,56 +27,57 @@
},
"license": "MIT",
"dependencies": {
"@contentful/f36-icons": "^4.23.2",
"@contentful/f36-tokens": "^4.0.1",
"@contentful/f36-icons": "^4.29.0",
"@contentful/f36-tokens": "^4.0.5",
"@contentful/live-preview": "^4.5.2",
"@contentful/rich-text-react-renderer": "^15.16.2",
"@next/bundle-analyzer": "^13.0.4",
"@next/bundle-analyzer": "^14.2.6",
"dotenv": "^16.0.3",
"graphql": "^16.6.0",
"next": "^13.4.1",
"i18next-browser-languagedetector": "^8.0.0",
"i18next-resources-to-backend": "^1.2.1",
"next": "^14.2.6",
"next-compose-plugins": "^2.2.1",
"next-i18next": "^12.1.0",
"next-pwa": "^5.6.0",
"next-seo": "^5.15.0",
"next-sitemap": "^3.1.32",
"react": "18.2.0",
"react-dom": "18.2.0",
"next-i18n-router": "^5.5.1",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-focus-lock": "^2.9.2",
"sharp": "^0.32.6"
"react-i18next": "^15.0.1",
"sharp": "^0.33.5"
},
"devDependencies": {
"@babel/eslint-parser": "^7.19.1",
"@contentful/rich-text-types": "^16.0.2",
"@graphql-codegen/cli": "2.13.12",
"@graphql-codegen/cli": "5.0.2",
"@graphql-codegen/client-preset": "1.1.4",
"@graphql-codegen/introspection": "2.2.1",
"@graphql-codegen/typescript-graphql-request": "^6.2.0",
"@svgr/webpack": "^6.5.1",
"@tailwindcss/typography": "^0.5.8",
"@types/negotiator": "^0.6.3",
"@types/node": "18.11.9",
"@types/react": "18.0.25",
"@types/react-dom": "18.0.9",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.32.0",
"autoprefixer": "^10.4.13",
"eslint": "8.26.0",
"eslint-config-next": "13.0.1",
"eslint-config-next": "14.2.7",
"eslint-config-prettier": "^8.3.0",
"eslint-import-resolver-typescript": "^2.4.0",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.22.0",
"eslint-plugin-react-hooks": "^4.2.0",
"husky": "^8.0.2",
"i18next": "^21.9.2",
"i18next": "^23.14.0",
"i18next-http-backend": "^1.4.4",
"lint-staged": "^13.0.3",
"postcss": "^8.4.19",
"prettier": "^2.7.1",
"prettier-plugin-tailwindcss": "^0.2.1",
"tailwind-merge": "^1.8.0",
"tailwindcss": "^3.2.4",
"typescript": "4.9.3",
"typescript-graphql-request": "^4.4.6"
"typescript": "5.5.4"
}
}
71 changes: 71 additions & 0 deletions src/app/[locale]/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { draftMode } from 'next/headers';
import { notFound } from 'next/navigation';

import { ArticleContent, ArticleHero, ArticleTileGrid } from '@src/components/features/article';
import { Container } from '@src/components/shared/container';
import initTranslations from '@src/i18n';
import { client, previewClient } from '@src/lib/client';

export async function generateStaticParams({
params: { locale },
}: {
params: { locale: string };
}): Promise<BlogPageProps['params'][]> {
const gqlClient = client;
const { pageBlogPostCollection } = await gqlClient.pageBlogPostCollection({ locale, limit: 100 });

if (!pageBlogPostCollection?.items) {
throw new Error('No blog posts found');
}

return pageBlogPostCollection.items
.filter((blogPost): blogPost is NonNullable<typeof blogPost> => Boolean(blogPost?.slug))
.map(blogPost => {
return {
locale,
slug: blogPost.slug!,
};
});
}

interface BlogPageProps {
params: {
locale: string;
slug: string;
};
}

export default async function Page({ params: { locale, slug } }: BlogPageProps) {
const { isEnabled: preview } = draftMode();
const gqlClient = preview ? previewClient : client;
const { t } = await initTranslations({ locale });
const { pageBlogPostCollection } = await gqlClient.pageBlogPost({ locale, slug, preview });
const { pageLandingCollection } = await gqlClient.pageLanding({ locale, preview });
const landingPage = pageLandingCollection?.items[0];
const blogPost = pageBlogPostCollection?.items[0];
const relatedPosts = blogPost?.relatedBlogPostsCollection?.items;
const isFeatured = Boolean(
blogPost?.slug && landingPage?.featuredBlogPost?.slug === blogPost.slug,
);

if (!blogPost) {
notFound();
}

return (
<>
<Container>
<ArticleHero article={blogPost} isFeatured={isFeatured} isReversedLayout={true} />
</Container>
<Container className="mt-8 max-w-4xl">
<ArticleContent article={blogPost} />
</Container>
{relatedPosts && (
<Container className="mt-8 max-w-5xl">
<h2 className="mb-4 md:mb-6">{t('article.relatedArticles')}</h2>
<ArticleTileGrid className="md:grid-cols-2" articles={relatedPosts} />
</Container>
)}
</>
);
}
70 changes: 70 additions & 0 deletions src/app/[locale]/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { dir } from 'i18next';
import type { Metadata, Viewport } from 'next';
import { Urbanist } from 'next/font/google';
import { draftMode } from 'next/headers';

import { ContentfulPreviewProvider } from '@src/components/features/contentful';
import TranslationsProvider from '@src/components/shared/i18n/TranslationProvider';
import { Footer } from '@src/components/templates/footer';
import { Header } from '@src/components/templates/header';
import initTranslations from '@src/i18n';
import { locales } from '@src/i18n/config';

export async function generateMetadata() {
const metatadata: Metadata = {
metadataBase: new URL(process.env.NEXT_PUBLIC_BASE_URL!),
other: {
'msapplication-TileColor': '#ffffff',
'msapplication-config': '/favicons/browserconfig.xml',
},
} as Metadata;

return metatadata;
}

export const viewport: Viewport = {
themeColor: '#ffffff',
};

export async function generateStaticParams(): Promise<LayoutProps['params'][]> {
return locales.map(locale => ({ locale }));
}

const urbanist = Urbanist({ subsets: ['latin'], variable: '--font-urbanist' });

interface LayoutProps {
children: React.ReactNode;
params: { locale: string };
}

export default async function PageLayout({ children, params }: LayoutProps) {
const { isEnabled: preview } = draftMode();
const { locale } = params;
const { resources } = await initTranslations({ locale });

return (
<html lang={locale} dir={dir(locale)}>
<head>
<link rel="mask-icon" href="/favicons/safari-pinned-tab.svg" color="#5bbad5" />
</head>

<body>
<TranslationsProvider locale={locale} resources={resources}>
<ContentfulPreviewProvider
locale={locale}
enableInspectorMode={preview}
enableLiveUpdates={preview}
targetOrigin={'https://app.contentful.com'}
>
<main className={`${urbanist.variable} font-sans`}>
<Header />
{children}
<Footer />
</main>
<div id="portal" className={`${urbanist.variable} font-sans`} />
</ContentfulPreviewProvider>
</TranslationsProvider>
</body>
</html>
);
}
20 changes: 20 additions & 0 deletions src/app/[locale]/not-found.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Link from 'next/link';

import { Container } from '@src/components/shared/container';
import initTranslations from '@src/i18n';
import { defaultLocale } from '@src/i18n/config';

export default async function NotFound() {
const { t } = await initTranslations({ locale: defaultLocale });

return (
<Container>
<h1 className="h2">{t('notFound.title')}</h1>
<p className="mt-4">
{t('notFound.description')}

<Link className="text-blue500" href="/" />
</p>
</Container>
);
}
Loading

0 comments on commit 4656dd7

Please sign in to comment.