diff --git a/apps/next-app/app/api/tweet/[id]/route.ts b/apps/next-app/app/api/tweet/[id]/route.ts index 993ebf1b..efe945ce 100644 --- a/apps/next-app/app/api/tweet/[id]/route.ts +++ b/apps/next-app/app/api/tweet/[id]/route.ts @@ -1,12 +1,14 @@ import { NextResponse } from 'next/server' import { getTweet } from 'react-tweet/api' - -export const fetchCache = 'only-cache' +import { cacheLife } from 'next/cache' export async function GET( _req: Request, { params }: RouteContext<'/api/tweet/[id]'> ) { + 'use cache' + cacheLife('days') + try { const { id } = await params const tweet = await getTweet(id) diff --git a/apps/next-app/app/light/[tweet]/page.tsx b/apps/next-app/app/light/[tweet]/page.tsx index 97e585dd..211abb7c 100644 --- a/apps/next-app/app/light/[tweet]/page.tsx +++ b/apps/next-app/app/light/[tweet]/page.tsx @@ -1,15 +1,21 @@ import { Tweet } from 'react-tweet' import { getTweet } from 'react-tweet/api' +import { cacheLife } from 'next/cache' import { components } from './tweet-components' type Props = { params: Promise<{ tweet: string }> } -export const revalidate = 1800 +export async function generateStaticParams() { + return [{ tweet: '1969515038512926823' }] +} export async function generateMetadata({ params }: Props) { - const id = await params.then((p) => p.tweet) + 'use cache' + cacheLife('hours') + + const { tweet: id } = await params const tweet = await getTweet(id).catch(() => undefined) if (!tweet) return { title: 'Next Tweet' } @@ -24,7 +30,14 @@ export async function generateMetadata({ params }: Props) { return { title: `${text}${username}` } } -export default async function Page({ params }: Props) { - const id = await params.then((p) => p.tweet) - return +async function TweetContent({ params }: Props) { + 'use cache' + cacheLife('hours') + + const { tweet } = await params + return +} + +export default function Page({ params }: Props) { + return } diff --git a/apps/next-app/app/light/cache/[tweet]/page.tsx b/apps/next-app/app/light/cache/[tweet]/page.tsx index 951bd701..dbdeabb8 100644 --- a/apps/next-app/app/light/cache/[tweet]/page.tsx +++ b/apps/next-app/app/light/cache/[tweet]/page.tsx @@ -2,11 +2,13 @@ import { Suspense } from 'react' import { TweetSkeleton } from 'react-tweet' import TweetPage from './tweet-page' -export const revalidate = 86400 +type Props = { + params: Promise<{ tweet: string }> +} -const Page = ({ params }: { params: { tweet: string } }) => ( +const Page = ({ params }: Props) => ( }> - + ) diff --git a/apps/next-app/app/light/cache/[tweet]/tweet-page.tsx b/apps/next-app/app/light/cache/[tweet]/tweet-page.tsx index c3160e85..033d4db6 100644 --- a/apps/next-app/app/light/cache/[tweet]/tweet-page.tsx +++ b/apps/next-app/app/light/cache/[tweet]/tweet-page.tsx @@ -1,14 +1,17 @@ -import { unstable_cache } from 'next/cache' -import { getTweet as _getTweet } from 'react-tweet/api' +import { cacheLife } from 'next/cache' +import { getTweet } from 'react-tweet/api' import { EmbeddedTweet, TweetNotFound } from 'react-tweet' -const getTweet = unstable_cache( - async (id: string) => _getTweet(id), - ['tweet'], - { revalidate: 3600 * 24 } -) +type Props = { + params: Promise<{ tweet: string }> +} + +const TweetPage = async ({ params }: Props) => { + 'use cache' + cacheLife('days') + + const { tweet: id } = await params -const TweetPage = async ({ id }: { id: string }) => { try { const tweet = await getTweet(id) return tweet ? : diff --git a/apps/next-app/app/light/suspense/[tweet]/page.tsx b/apps/next-app/app/light/suspense/[tweet]/page.tsx index 67a1b32d..dbdeabb8 100644 --- a/apps/next-app/app/light/suspense/[tweet]/page.tsx +++ b/apps/next-app/app/light/suspense/[tweet]/page.tsx @@ -2,11 +2,13 @@ import { Suspense } from 'react' import { TweetSkeleton } from 'react-tweet' import TweetPage from './tweet-page' -export const revalidate = 3600 +type Props = { + params: Promise<{ tweet: string }> +} -const Page = ({ params }: { params: { tweet: string } }) => ( +const Page = ({ params }: Props) => ( }> - + ) diff --git a/apps/next-app/app/light/suspense/[tweet]/tweet-page.tsx b/apps/next-app/app/light/suspense/[tweet]/tweet-page.tsx index 82338785..b79914cf 100644 --- a/apps/next-app/app/light/suspense/[tweet]/tweet-page.tsx +++ b/apps/next-app/app/light/suspense/[tweet]/tweet-page.tsx @@ -1,7 +1,13 @@ import { getTweet } from 'react-tweet/api' import { EmbeddedTweet, TweetNotFound } from 'react-tweet' -const TweetPage = async ({ id }: { id: string }) => { +type Props = { + params: Promise<{ tweet: string }> +} + +const TweetPage = async ({ params }: Props) => { + const { tweet: id } = await params + try { const tweet = await getTweet(id) return tweet ? : diff --git a/apps/next-app/app/light/vercel-kv/[tweet]/page.tsx b/apps/next-app/app/light/vercel-kv/[tweet]/page.tsx index 951bd701..dbdeabb8 100644 --- a/apps/next-app/app/light/vercel-kv/[tweet]/page.tsx +++ b/apps/next-app/app/light/vercel-kv/[tweet]/page.tsx @@ -2,11 +2,13 @@ import { Suspense } from 'react' import { TweetSkeleton } from 'react-tweet' import TweetPage from './tweet-page' -export const revalidate = 86400 +type Props = { + params: Promise<{ tweet: string }> +} -const Page = ({ params }: { params: { tweet: string } }) => ( +const Page = ({ params }: Props) => ( }> - + ) diff --git a/apps/next-app/app/light/vercel-kv/[tweet]/tweet-page.tsx b/apps/next-app/app/light/vercel-kv/[tweet]/tweet-page.tsx index fdf944f7..d5c9eeac 100644 --- a/apps/next-app/app/light/vercel-kv/[tweet]/tweet-page.tsx +++ b/apps/next-app/app/light/vercel-kv/[tweet]/tweet-page.tsx @@ -2,6 +2,10 @@ import { fetchTweet, Tweet } from 'react-tweet/api' import { EmbeddedTweet, TweetNotFound } from 'react-tweet' import { kv } from '@vercel/kv' +type Props = { + params: Promise<{ tweet: string }> +} + async function getTweet( id: string, fetchOptions?: RequestInit @@ -25,7 +29,9 @@ async function getTweet( return cachedTweet ?? undefined } -const TweetPage = async ({ id }: { id: string }) => { +const TweetPage = async ({ params }: Props) => { + const { tweet: id } = await params + try { const tweet = await getTweet(id) return tweet ? : diff --git a/apps/next-app/next.config.mjs b/apps/next-app/next.config.mjs index 38519916..7af131d1 100644 --- a/apps/next-app/next.config.mjs +++ b/apps/next-app/next.config.mjs @@ -4,6 +4,7 @@ const withMDX = mdx() /** @type {import('next').NextConfig} */ const nextConfig = { + cacheComponents: true, pageExtensions: ['ts', 'tsx', 'js', 'jsx', 'md', 'mdx'], images: { remotePatterns: [ diff --git a/apps/next-app/package.json b/apps/next-app/package.json index f85a018d..b44de4ae 100644 --- a/apps/next-app/package.json +++ b/apps/next-app/package.json @@ -15,7 +15,7 @@ "@next/mdx": "^15.5.3", "@vercel/kv": "^3.0.0", "clsx": "^2.1.1", - "next": "15.6.0-canary.59", + "next": "latest", "react": "^19.1.1", "react-dom": "^19.1.1", "react-tweet": "workspace:*" diff --git a/apps/next-app/tsconfig.json b/apps/next-app/tsconfig.json index 476c62cb..609ae051 100644 --- a/apps/next-app/tsconfig.json +++ b/apps/next-app/tsconfig.json @@ -29,7 +29,8 @@ "next-env.d.ts", "**/*.ts", "**/*.tsx", - ".next/types/**/*.ts" + ".next/types/**/*.ts", + ".next/dev/types/**/*.ts" ], "exclude": [ "node_modules" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9e2dcaa3..e5180183 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -91,8 +91,8 @@ importers: specifier: ^2.1.1 version: 2.1.1 next: - specifier: 15.6.0-canary.59 - version: 15.6.0-canary.59(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + specifier: latest + version: 16.1.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react: specifier: ^19.1.1 version: 19.1.1 @@ -953,8 +953,8 @@ packages: '@next/env@15.5.8': resolution: {integrity: sha512-ejZHa3ogTxcy851dFoNtfB5B2h7AbSAtHbR5CymUlnz4yW1QjHNufVpvTu8PTnWBKFKjrd4k6Gbi2SsCiJKvxw==} - '@next/env@15.6.0-canary.59': - resolution: {integrity: sha512-D5msVvBiiJrqAW3MPXP4rR7teMeCcMLCK3yTSCGM4XuuzAcO8Eb4RZtbSPS0zgvFKu9r5hv5eaTXlNmgNmZ5TQ==} + '@next/env@16.1.5': + resolution: {integrity: sha512-CRSCPJiSZoi4Pn69RYBDI9R7YK2g59vLexPQFXY0eyw+ILevIenCywzg+DqmlBik9zszEnw2HLFOUlLAcJbL7g==} '@next/eslint-plugin-next@14.2.32': resolution: {integrity: sha512-tyZMX8g4cWg/uPW4NxiJK13t62Pab47SKGJGVZJa6YtFwtfrXovH4j1n9tdpRdXW03PGQBugYEVGM7OhWfytdA==} @@ -985,8 +985,8 @@ packages: cpu: [arm64] os: [darwin] - '@next/swc-darwin-arm64@15.6.0-canary.58': - resolution: {integrity: sha512-jGawwiKITJHOH8dSbTqfjVvCf+DesljZhtvh9LKCrO+1octLlGyDAbEQw5WEzrXCch5LWrdSqPyKft0/9LeniA==} + '@next/swc-darwin-arm64@16.1.5': + resolution: {integrity: sha512-eK7Wdm3Hjy/SCL7TevlH0C9chrpeOYWx2iR7guJDaz4zEQKWcS1IMVfMb9UKBFMg1XgzcPTYPIp1Vcpukkjg6Q==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] @@ -1003,8 +1003,8 @@ packages: cpu: [x64] os: [darwin] - '@next/swc-darwin-x64@15.6.0-canary.58': - resolution: {integrity: sha512-iD15Eav7Y7lQOCFvsPf9NMwo3dFrHZMX4wghrEysLuwOEJC9zM0jOSb1hdSqZwf1Odn86CIiJUvXH1UcfAm6og==} + '@next/swc-darwin-x64@16.1.5': + resolution: {integrity: sha512-foQscSHD1dCuxBmGkbIr6ScAUF6pRoDZP6czajyvmXPAOFNnQUJu2Os1SGELODjKp/ULa4fulnBWoHV3XdPLfA==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] @@ -1021,8 +1021,8 @@ packages: cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-gnu@15.6.0-canary.58': - resolution: {integrity: sha512-b8ayBG/wrycIilOFP/zU6yPQI8UVMtrQfowNaoCvG7FIuu5Fpa7MwPEGWXPyvwn2qQM5fDSsVGQOrjQ6gWLTbA==} + '@next/swc-linux-arm64-gnu@16.1.5': + resolution: {integrity: sha512-qNIb42o3C02ccIeSeKjacF3HXotGsxh/FMk/rSRmCzOVMtoWH88odn2uZqF8RLsSUWHcAqTgYmPD3pZ03L9ZAA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -1039,8 +1039,8 @@ packages: cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-musl@15.6.0-canary.58': - resolution: {integrity: sha512-KMYPUdBTAITdgxRNjMKdG85bHsn3wu0KWPV2nftoov2/dVs5eFJ47w+m4upPdTgBXRAHY50OvS/nzf5mN/TXeQ==} + '@next/swc-linux-arm64-musl@16.1.5': + resolution: {integrity: sha512-U+kBxGUY1xMAzDTXmuVMfhaWUZQAwzRaHJ/I6ihtR5SbTVUEaDRiEU9YMjy1obBWpdOBuk1bcm+tsmifYSygfw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -1057,8 +1057,8 @@ packages: cpu: [x64] os: [linux] - '@next/swc-linux-x64-gnu@15.6.0-canary.58': - resolution: {integrity: sha512-myknT/if7wuwss0B/1Le7ymlN0Zr/DsfGji8b+XcqeFhoy1GxQerfTlrsblZTB6EIPIex1QPRUbpIcy+N9Qfpw==} + '@next/swc-linux-x64-gnu@16.1.5': + resolution: {integrity: sha512-gq2UtoCpN7Ke/7tKaU7i/1L7eFLfhMbXjNghSv0MVGF1dmuoaPeEVDvkDuO/9LVa44h5gqpWeJ4mRRznjDv7LA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -1075,8 +1075,8 @@ packages: cpu: [x64] os: [linux] - '@next/swc-linux-x64-musl@15.6.0-canary.58': - resolution: {integrity: sha512-3A1YLtmuot0pnZqDHV2iAfUrvQS0zp7xXUlqNb8flAJAu1Civ+2qt94l0kTfUjWHtFFUENyt2yEcXEqxuxEJfg==} + '@next/swc-linux-x64-musl@16.1.5': + resolution: {integrity: sha512-bQWSE729PbXT6mMklWLf8dotislPle2L70E9q6iwETYEOt092GDn0c+TTNj26AjmeceSsC4ndyGsK5nKqHYXjQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -1093,8 +1093,8 @@ packages: cpu: [arm64] os: [win32] - '@next/swc-win32-arm64-msvc@15.6.0-canary.58': - resolution: {integrity: sha512-3hkMBi/Zbatqi9vwnh1zuOWQerS4CtUptn9cj4NRtVAJurzhfQBwz8RJIq/5f85XDkq0LxDrhyABZ+6RU7Un7Q==} + '@next/swc-win32-arm64-msvc@16.1.5': + resolution: {integrity: sha512-LZli0anutkIllMtTAWZlDqdfvjWX/ch8AFK5WgkNTvaqwlouiD1oHM+WW8RXMiL0+vAkAJyAGEzPPjO+hnrSNQ==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] @@ -1117,8 +1117,8 @@ packages: cpu: [x64] os: [win32] - '@next/swc-win32-x64-msvc@15.6.0-canary.58': - resolution: {integrity: sha512-CFB6BzqgYJ7yJvoji0KD5nWf88JN5/iliiLn/kfzxUMvfaKmoYLrGZwRuePrAwLdBpczEsgcmuER6YuT9/pZLw==} + '@next/swc-win32-x64-msvc@16.1.5': + resolution: {integrity: sha512-7is37HJTNQGhjPpQbkKjKEboHYQnCgpVt/4rBrrln0D9nderNxZ8ZWs8w1fAtzUx7wEyYjQ+/13myFgFj6K2Ng==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -3830,8 +3830,8 @@ packages: sass: optional: true - next@15.6.0-canary.59: - resolution: {integrity: sha512-FOKHnHEVqtbMj2eQfgRgEkzEds/hqjz5JRBjLhT7UgPtvs36Vzc7RU9mh8lOZt/TONS7jVs+5ilv194QA/wdnQ==} + next@16.1.5: + resolution: {integrity: sha512-f+wE+NSbiQgh3DSAlTaw2FwY5yGdVViAtp8TotNQj4kk4Q8Bh1sC/aL9aH+Rg1YAVn18OYXsRDT7U/079jgP7w==} engines: {node: '>=20.9.0'} hasBin: true peerDependencies: @@ -5853,7 +5853,7 @@ snapshots: '@next/env@15.5.8': {} - '@next/env@15.6.0-canary.59': {} + '@next/env@16.1.5': {} '@next/eslint-plugin-next@14.2.32': dependencies: @@ -5875,7 +5875,7 @@ snapshots: '@next/swc-darwin-arm64@15.5.7': optional: true - '@next/swc-darwin-arm64@15.6.0-canary.58': + '@next/swc-darwin-arm64@16.1.5': optional: true '@next/swc-darwin-x64@14.2.33': @@ -5884,7 +5884,7 @@ snapshots: '@next/swc-darwin-x64@15.5.7': optional: true - '@next/swc-darwin-x64@15.6.0-canary.58': + '@next/swc-darwin-x64@16.1.5': optional: true '@next/swc-linux-arm64-gnu@14.2.33': @@ -5893,7 +5893,7 @@ snapshots: '@next/swc-linux-arm64-gnu@15.5.7': optional: true - '@next/swc-linux-arm64-gnu@15.6.0-canary.58': + '@next/swc-linux-arm64-gnu@16.1.5': optional: true '@next/swc-linux-arm64-musl@14.2.33': @@ -5902,7 +5902,7 @@ snapshots: '@next/swc-linux-arm64-musl@15.5.7': optional: true - '@next/swc-linux-arm64-musl@15.6.0-canary.58': + '@next/swc-linux-arm64-musl@16.1.5': optional: true '@next/swc-linux-x64-gnu@14.2.33': @@ -5911,7 +5911,7 @@ snapshots: '@next/swc-linux-x64-gnu@15.5.7': optional: true - '@next/swc-linux-x64-gnu@15.6.0-canary.58': + '@next/swc-linux-x64-gnu@16.1.5': optional: true '@next/swc-linux-x64-musl@14.2.33': @@ -5920,7 +5920,7 @@ snapshots: '@next/swc-linux-x64-musl@15.5.7': optional: true - '@next/swc-linux-x64-musl@15.6.0-canary.58': + '@next/swc-linux-x64-musl@16.1.5': optional: true '@next/swc-win32-arm64-msvc@14.2.33': @@ -5929,7 +5929,7 @@ snapshots: '@next/swc-win32-arm64-msvc@15.5.7': optional: true - '@next/swc-win32-arm64-msvc@15.6.0-canary.58': + '@next/swc-win32-arm64-msvc@16.1.5': optional: true '@next/swc-win32-ia32-msvc@14.2.33': @@ -5941,7 +5941,7 @@ snapshots: '@next/swc-win32-x64-msvc@15.5.7': optional: true - '@next/swc-win32-x64-msvc@15.6.0-canary.58': + '@next/swc-win32-x64-msvc@16.1.5': optional: true '@nodelib/fs.scandir@2.1.5': @@ -9354,24 +9354,25 @@ snapshots: - '@babel/core' - babel-plugin-macros - next@15.6.0-canary.59(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + next@16.1.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: - '@next/env': 15.6.0-canary.59 + '@next/env': 16.1.5 '@swc/helpers': 0.5.15 + baseline-browser-mapping: 2.8.6 caniuse-lite: 1.0.30001743 postcss: 8.4.31 react: 19.1.1 react-dom: 19.1.1(react@19.1.1) styled-jsx: 5.1.6(react@19.1.1) optionalDependencies: - '@next/swc-darwin-arm64': 15.6.0-canary.58 - '@next/swc-darwin-x64': 15.6.0-canary.58 - '@next/swc-linux-arm64-gnu': 15.6.0-canary.58 - '@next/swc-linux-arm64-musl': 15.6.0-canary.58 - '@next/swc-linux-x64-gnu': 15.6.0-canary.58 - '@next/swc-linux-x64-musl': 15.6.0-canary.58 - '@next/swc-win32-arm64-msvc': 15.6.0-canary.58 - '@next/swc-win32-x64-msvc': 15.6.0-canary.58 + '@next/swc-darwin-arm64': 16.1.5 + '@next/swc-darwin-x64': 16.1.5 + '@next/swc-linux-arm64-gnu': 16.1.5 + '@next/swc-linux-arm64-musl': 16.1.5 + '@next/swc-linux-x64-gnu': 16.1.5 + '@next/swc-linux-x64-musl': 16.1.5 + '@next/swc-win32-arm64-msvc': 16.1.5 + '@next/swc-win32-x64-msvc': 16.1.5 sharp: 0.34.4 transitivePeerDependencies: - '@babel/core'