Dev Journal #5: A UI to list links
June 10, 2023The next step is to create the first UI page to display the list of existing links. Even though I followed SST’s docs for creating a NextJS project, linking NextJS, SST, and MUI together was fraught.
Bring NextJS and MUI Online
To get it all in sync, I ended up cloning the SST NextJS quickstart example and copying over files until I was able to see Next’s Hello World
UI:
Then, I did the same with MUI’s NextJS (Typescript) example until I could that Hello World
UI:
You can view these changes in the Next UI works in dev and Add MUI PRs.
I’m eternally grateful to the devs that have written countless examples for the MUI and SST projects; without those examples, I don’t think I would’ve been able to move forward on this project with these tools.
Poll the API for Links
Finally, let’s connect the UI to the API data! First, we’ll expose the api
construct in stacks/API.ts
so that we can bind it to the UI:
// ...
stack.addOutputs({
ApiEndpoint: api.url,
});
return { api };
}
Then bind the api
to the site
under stacks/Site.ts
:
export function Site({ stack }: StackContext) {
const { api } = use(API);
const site = new NextjsSite(stack, "site", {
bind: [api],
});
On the index page (src/pages/index.tsx
), we can create a Link
type and use getServerSideProps
to fetch data from the API:
type Link = {
shortPath: string;
url: string;
uid: string;
};
export const getServerSideProps: GetServerSideProps<{
links: Link[];
}> = async (context) => {
const endpoint = `${Api.api.url}/links`;
const res = await fetch(endpoint);
const data = await res.json();
return { props: data.body };
};
There’s a possible breakdown between the UI and API here if the Link
type skews from what the API returns, so I created an issue to revisit this in the future. In that same file, we’ll add some basic p
tags for each link we receive:
export default function Home({ links }: { links: Link[] }) {
return (
<Container maxWidth="lg">
{/* ... */}
{links &&
links.map((link) => (
<Typography
variant="body1"
component="p"
gutterBottom
key={link.uid}
>
{link.shortPath} - {link.url}
</Typography>
))}
One last thing: NextJS requires an experimental flag in next.config.js
to make this work. I think it’s to allow async
calls inside getServerProps
:
const nextConfig = {
reactStrictMode: true,
webpack(config) {
config.experiments = { ...config.experiments, topLevelAwait: true };
return config;
},
};
And there we go, links! You can view this code on the Index shows list of links PR.