This is how I tried to create a kind of redirection service in my nextJS application.
There are two options: The content of a file on my server will be streamed or there is a simple link and the user is directly redirected.
This is done in page router.
Now I would like to migrate this to the app router. But there is no getServerSideProps
in the app router anymore. Instead there are server compontents.
pages/[hash].tsx
import { GridFSBucket, GridFSFile, MongoServerError, ObjectId } from 'mongodb'
import { GetServerSideProps, NextPage } from 'next'
import Head from 'next/head'
export const getServerSideProps: GetServerSideProps = async ({
res,
req,
query: { hash }
}) => {
if (!hash) return { notFound: true }
try {
const database = await mongodb()
const Data = database.collection('data')
const { fileId, link } = (await Data.findOne({ uid: hash })) || {}
if (fileId) {
const bucket = new GridFSBucket(database)
const id = new ObjectId(fileId)
const files: GridFSFile[] = await bucket.find({ _id: id }).toArray()
const file = files[0]
const { contentType } = file
// Send header
const header = { 'Content-Type': contentType }
let status = 200
res.writeHead(status, header)
// Stream data
bucket
.openDownloadStream(id, options)
.on('data', (chunk) => {
res.write(chunk)
})
.on('end', () => {
res.end()
})
.on('error', (err) => {
throw err
})
} else if (link) {
return {
redirect: {
destination: link,
permanent: false
}
}
}
return {
props: {}
}
} catch (error) {
if (error instanceof MongoServerError) {
console.error(error)
}
throw error
}
}
const HashPage: NextPage = () => {
return (
<>
<Head>
<title>Redirection</title>
</Head>
<div>Error: Content doesn't exist</div>
</>
)
}
export default HashPage
In my case header are send and some content is streamed or there is a direct redirection. How do I do this correctly in nextJS? Maybe this content has to be moved to an api
folder? Do I need a middleware?
Or maybe moved to app/[hash]/page.tsx
? But in this case I don’t know where to get res, req, query: { hash }
from and how to handle to show an error component in case of an error.
app/[hash]/page.tsx
const HashPage: NextPage = async () => {
await getServerSideProps() // <- missing props here
return (
<div>Error: Content doesn't exist</div>
)
}
export default HashPage