#Live preview with NextJS

15 messages ยท Page 1 of 1 (latest)

solar comet
#

I just recently discovered Payload and fell in love with it immediately.

I'm now trying to set up a live preview with the NextJS Frontend which is deployed on vercel. The goal would be to have 2 windows open, edit the content in payload on the left side, see the changes on the preview website in real time (small delays are fine).

My Idea was to set up a separate deploy with an auth wall on a subdomain (preview.xyz.com) that get's the data in draft mode after the user has logged in with his payload credentials. Using the autosave feature, the content on the preview page should be updated every 2 seconds.

One unsolved question is how to actually refresh the page content: I could let the page query the content every 2 seconds, or maybe set up a websocket connection to the payload express app? Since I haven't done anything similar before, I'd love to hear if anyone thinks this will work, or if there are better/simpler ways to implement this.

midnight wagon
#

Hey @solar comet โ€” I do think that a simple websocket or messaging service would be the best way to do this

#

and this is on our radar to build into Payload for sure, natively, although as of right now, you could do this on your own using SocketIO or similar

crystal canopy
#

Sandro you are doing the lords work, if you figure it out lmk. Would love to implement a live preview, I wish there was documentation on implementation of just the preview functionality with next similar to what Prismic, DatoCMS, etc... Trying to hack something together to show team proof of concept

fossil whale
#

Same here, would love this! As of right now I just refetch the draft data each 2seconds on a preview route.

Using SocketIO seems interesting for sure.

solar comet
#

I'll post in here when I've figured sth out ๐Ÿ˜‰

solar comet
#

@crystal canopy @fossil whale I actually managed to get it working. Check my post in the Showcase Channel or hmu ๐Ÿ™‚

fossil whale
#

Very nice! I would love to try and implement this in my project. It's SvelteKit tho, but the functionality stays the same I guess.

solar comet
#

Yup, you just have to implement a functionality in the frontend to 1. Authenticate a user (send a login request to payload) and 2. if logged in, listen to update calls from the server. This is a bit tricky if you're using Nextjs along with SSG etc. but I don't know about sveltekit

#

Here's what you have to do serverside ```javascript
// Instead of just calling app.listen
// app.listen(process.env.PAYLOAD_PUBLIC_INTERNAL_SERVER_URL.split(':')[2]);

// create an http server (or https if you aren't using a reverse proxy)
const server = http.createServer(app)
server.listen(process.env.PAYLOAD_PUBLIC_INTERNAL_SERVER_URL.split(':')[2], () => {
console.log(HTTP Server running on port ${process.env.PAYLOAD_PUBLIC_INTERNAL_SERVER_URL.split(':')[2]});
});

// Socket.io
// Now pass the server instance to socket io, to create a websocket server on the same port
const io = require('socket.io')(server, {
cors: {
origin: process.env.WHITELIST_ORIGINS.split(','),
}
});

io.on('connection', (socket) => {
console.log('New client connected');

socket.on('disconnect', () => {
// console.log('Client disconnected')
});
})

// You can't call io.emit directly from the payload hooks, it throws errors.
// As a workaround, you can set up a simple endpoint that emits the update
app.post('/updatePreview', (req, res) => {
console.log('update preview called')
// Check if authorization header contains PAYLOAD_SECRET
if (req.headers.authorization !== process.env.PAYLOAD_PUBLIC_SERVER_SECRET) {
res.sendStatus(401)
return
}
io.emit('update')
})

#

Now, in the payload hooks, add an afterChange Hook:

if (args.doc._status !== 'published') {
            try {
              axios({
                method: 'post',
                url: `${process.env.PAYLOAD_PUBLIC_INTERNAL_SERVER_URL}/updatePreview`,
                headers: {
                  'Authorization': `${process.env.PAYLOAD_PUBLIC_SERVER_SECRET}`
                }
              })
            } catch (e) {
              console.error(e)
            }
            return console.log('Not published, skipping revalidation')

This will just call the api endpoint you've just set up and emit the update message

long crater
#

if you write code blocks and want them to be syntax highlighted for readability, you can append the language after the 3 back ticks. For typescript it would be 3 back ticks followed by the word typescript

solar comet
#

Oh damn thanks @long crater ! This is my first time really using discord haha

long crater
#

No prob! Was just letting you know ๐Ÿ˜ƒ

fossil whale
#

@solar comet finally had the chance to test this out. Works like a charm!