Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Update to Next.js 14 #51

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/next/app/(generated)/bio/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
'use client'
// -i- Automatically generated by 'yarn link-routes', do not modify manually
export { default, dynamic, generateStaticParams } from 'links-page/routes/bio/[slug]'
export { default, dynamic } from 'links-page/routes/bio/[slug]'
2 changes: 1 addition & 1 deletion apps/next/app/ClientRootLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ setPublicEnvVars({

const NextClientRootLayout = (props: { children: React.ReactNode }) => {
// Props
const { children } = props
const { children } = props // FIXME: Why is children null on hydration??

// -- Fonts --

Expand Down
2 changes: 2 additions & 0 deletions apps/next/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import NextClientRootLayout from './ClientRootLayout'

/* --- <NextRootLayout/> ----------------------------------------------------------------------- */

// FIXME: Why is children null when passing it to NextClientRootLayout?

const NextRootLayout = ({ children }: { children: React.ReactNode }) => (
<Document>
<NextClientRootLayout>{children}</NextClientRootLayout>
Expand Down
9 changes: 8 additions & 1 deletion apps/next/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,14 @@ const nextConfig = {
ignoreBuildErrors: true,
},
images: {
domains: ['i3.ytimg.com'],
remotePatterns: [
{
protocol: 'https',
hostname: 'i3.ytimg.com',
// port: '',
// pathname: '/account123/**',
},
],
},
webpack: (config, { isServer }) => {
// -i- Run aetherspace automation scripts in DEV mode
Expand Down
4 changes: 2 additions & 2 deletions apps/next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
"app": "*",
"encoding": "^0.1.13",
"expo-asset-web": "npm:expo-asset@8.7.0",
"next": "13.4.8",
"next": "14.0.0",
"next-fonts": "^1.5.1",
"next-images": "^1.8.5",
"next-pwa": "^5.6.0",
"next-transpile-modules": "^10.0.0",
"next-transpile-modules": "^10.0.1",
"raf": "^3.4.1",
"registries": "*",
"setimmediate": "^1.0.5",
Expand Down
2 changes: 0 additions & 2 deletions features/app-core/hooks/useLoadFonts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ const useLoadFonts = () => {
Roboto700: Roboto_700Bold,
Roboto800: Roboto_900Black, // Fallback
Roboto900: Roboto_900Black,
// - Icon Fonts -
AntDesign: require('@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/AntDesign.ttf'),
}

const [googleFontsLoaded, googleFontsError] = useFonts(fontsToLoad)
Expand Down
2 changes: 1 addition & 1 deletion features/app-core/routes/opengraph-image.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable @next/next/no-img-element */
import React from 'react'
import { ImageResponse } from 'next/server'
import { ImageResponse } from 'next/og'

/* --- Segments -------------------------------------------------------------------------------- */

Expand Down
17 changes: 0 additions & 17 deletions features/cv-page/icons/registry.tsx

This file was deleted.

8 changes: 5 additions & 3 deletions features/cv-page/screens/ResumeScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -269,9 +269,11 @@ export const ResumeScreenRouteDataConfig = {
// -i- https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config
export const dynamic = 'force-static' // 'auto' | 'force-dynamic' | 'error' | 'force-static'

export const generateStaticParams = async (): Promise<TResumeScreenParams[]> => {
return [{ slug: 'codinsonn' }]
}
// TODO: Figure out how to generate static params in Next.js 14 while also needing to use client components
// -!- Error: Page "/(generated)/bio/[slug]/page" cannot use both "use client" and export function "generateStaticPar...()".
// export const generateDisabledStaticParams = async (): Promise<TResumeScreenParams[]> => {
// return [{ slug: 'codinsonn' }]
// }

/* --- <ResumeScreen/> ------------------------------------------------------------------------- */

Expand Down
2 changes: 1 addition & 1 deletion features/links-page/routes/bio/[slug].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ const PageScreen = (props: bioScreen.BioScreenProps) => (
/* --- Exports --------------------------------------------------------------------------------- */

export const dynamic = bioScreen.dynamic
export const generateStaticParams = bioScreen.generateStaticParams
// export const generateDisabledStaticParams = bioScreen.generateDisabledStaticParams

export default PageScreen
8 changes: 5 additions & 3 deletions features/links-page/screens/BioScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,11 @@

export const dynamic = 'force-static' // 'auto' | 'force-dynamic' | 'error' | 'force-static'

export const generateStaticParams = async (): Promise<BioScreenParams[]> => {
return [{ slug: 'codinsonn' }]
}
// TODO: Figure out how to generate static params in Next.js 14 while also needing to use client components
// -!- Error: Page "/(generated)/bio/[slug]/page" cannot use both "use client" and export function "generateStaticPar...()".
// export const generateDisabledStaticParams = async (): Promise<BioScreenParams[]> => {
// return [{ slug: 'codinsonn' }]
// }

/* --- <BioScreen/> ---------------------------------------------------------------------------- */

Expand All @@ -112,7 +114,7 @@
// Data
const [bioData, { error }] = useAetherRoute(props, screenConfig)
const { pathname } = useAetherNav()
const { colorScheme, toggleColorScheme } = useAetherContext()

Check warning on line 117 in features/links-page/screens/BioScreen.tsx

View workflow job for this annotation

GitHub Actions / check-linting

'colorScheme' is assigned a value but never used. Allowed unused vars must match /_/u

// Vars
const ICON_SIZE = 27
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"packages/*"
],
"engines": {
"node": ">=18.0.0"
"node": ">=18.17.0"
},
"browser": {
"fs": false,
Expand Down
95 changes: 0 additions & 95 deletions packages/@aetherspace/components/AetherIcon/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ There’s many different ways to use icons and icon sets in Aetherspace. Here’
→ SSR support, fast & easy, no layout shift on web, limited options
- Custom SVG components using `react-native-svg`
→ SSR support, can [convert from .svg file](https://transform.tools/svg-to-react-native), but could be more time-consuming
- Third party iconfont libraries, such as `@expo/vector-icons`
→ Fast & easy, needs icon font preloaded, layout shift on web, locked out of SWC
- Image icons through src urls
→ Straight forward, easy, not super optimised, fixed colors, layout shift on web

Expand Down Expand Up @@ -155,99 +153,6 @@ Downsides of this strategy:
- Time consuming: Requires some copy-pasting between transform tools and your code
- Therefore, even if it’s most reliable and configurable, also not very fast or scalable

## Using `@expo/vector-icons`

[Expo Docs: @expo/vector-icons](https://docs.expo.dev/guides/icons/)

> Check which iconset you want to use and how to use them on [https://icons.expo.fyi/](https://icons.expo.fyi/)

Benefits of using this strategy:

- Fast, choose icons from existing third party icon providers
- Most @expo/vector-icons are also compatible with the web

Downsides of using icon fonts under the hood:

- You’ll need to preload your icon font somehow, easy on mobile but harder on web
- Loading flicker, meaning you might not see the icon immediately if the icon font isn’t loaded yet
- Cannot use Next.js’s SWC compiler when using any of the @expo/vector-icons (no loader for importing .ttf files)

Example usage:

```tsx
import { AntDesign } from '@expo/vector-icons'

<AntDesign
name="caretup"
size={24}
color="#333333"
/>
```

Example preloading of icon font on mobile:

`/features/app-core/hooks/useLoadFonts.ts`

```tsx
'use client'
import { useFonts } from 'expo-font'
import { /* Google Fonts */ } from '@expo-google-fonts/roboto'

/* --- useLoadFonts() -------------------------------------------------------------------------- */

const useLoadFonts = () => {
const fontsToLoad = {
// - Google Fonts -
/* ... */
// - Icon Fonts -
AntDesign: require('@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/AntDesign.ttf'),
// -!- important: always double check this path (^) for your icon fonts
}

const [fontsLoaded, fontsError] = useFonts(fontsToLoad)

if (fontsError) console.error('fontErrors:', fontsLoaded)

// -- Return --

return fontsLoaded // <- Keep splash screen open until this is true
}

/* --- Exports --------------------------------------------------------------------------------- */

export default useLoadFonts
```

Example usage with `<AetherIcon/>`

`/packages/{workspace-folder}/icons/registry.tsx`

```tsx
import React from 'react'
import { registerIconRenderer } from 'aetherspace/utils'
import { AntDesign } from '@expo/vector-icons'
import { ComponentProps } from 'react'

/** --- iconRegistry --------------------------------------------------------------------------- */
/** -i- Register any icons by preferred AetherIcon "name" key */
export const iconRegistry = {
// Register any icons from e.g. AntDesign you want by
// registering them by strings 👇 array (readonly) + render function
...registerIconRenderer(['caretup'] as const, ({ name, size, fill, ...restIconProps }) => (
<AntDesign
name={name as ComponentProps<typeof AntDesign>['name']}
size={size}
color={fill}
{...restIconProps}
/>
)),
} as const // <-- Readonly is important here for accurate type hints
```

```tsx
<AetherIcon name="caretup" size={24} fill="#333333" />
```

## Using `AetherImage` with `.svg` files

> Using `AetherImage` with `.svg` files might be the most bundle size friendly way of using SVGs in your app. Since it will always result in only using the SVGs that you actually use in your app.
Expand Down
24 changes: 9 additions & 15 deletions packages/@aetherspace/docs/addons/gqlPlaygroundAddon.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,19 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var react_1 = require("react");
var addons_1 = require("@storybook/addons");
const react_1 = require("react");
const addons_1 = require("@storybook/addons");
/* --- GraphQL Storybook Plugin ---------------------------------------------------------------- */
addons_1.addons.register('/graphql', function () {
addons_1.addons.register('/graphql', () => {
addons_1.addons.add('graphql-playground/tab', {
type: addons_1.types.TAB,
title: 'GraphQL',
route: function (_a) {
var storyId = _a.storyId;
return "/graphql/".concat(storyId);
},
match: function (_a) {
var viewMode = _a.viewMode;
return viewMode === 'graphql';
},
render: function () {
var graphqlUrl = 'http://localhost:3000/api/graphql';
var isDev = process.env.NODE_ENV === 'development';
route: ({ storyId }) => `/graphql/${storyId}`,
match: ({ viewMode }) => viewMode === 'graphql',
render: () => {
let graphqlUrl = 'http://localhost:3000/api/graphql';
const isDev = process.env.NODE_ENV === 'development';
if (!isDev)
graphqlUrl = "".concat(process.env.STORYBOOK_BACKEND_URL, "/api/graphql");
graphqlUrl = `${process.env.STORYBOOK_BACKEND_URL}/api/graphql`;
return (0, react_1.createElement)('iframe', {
style: { width: '100%', height: '100%' },
src: graphqlUrl,
Expand Down
1 change: 0 additions & 1 deletion packages/@config/transpiledModules.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ module.exports = [
// - Modules -
'twrnc',
'@react-native/assets-registry',
'@expo/vector-icons',
// - Packages & Features -
...transpiledWorkspaces,
]
2 changes: 0 additions & 2 deletions packages/@registries/icons.generated.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
// -i- Auto generated with 'yarn ats collect-icons'
import { iconRegistry as cvPageIcons } from '../../features/cv-page/icons/registry'
import { iconRegistry as linksPageIcons } from '../../features/links-page/icons/registry'
import { iconRegistry as aetherspaceIcons } from '../../packages/@aetherspace/icons/registry'
import { iconRegistry as greenStackIconsIcons } from '../../packages/@green-stack-icons/icons/registry'

/* --- Exports --------------------------------------------------------------------------------- */

export const REGISTERED_ICONS = {
...cvPageIcons,
...linksPageIcons,
...aetherspaceIcons,
...greenStackIconsIcons,
Expand Down
Loading
Loading