Skip to content
This repository has been archived by the owner on May 10, 2021. It is now read-only.

Commit

Permalink
Support for i18n in Next 10 (#75)
Browse files Browse the repository at this point in the history
* rough pass at i18n ssg breaking changes in next 10

* update withoutProps/redirects to accommodate defaultLocale

* very dirty Just Working i18n for most cases

* pre clean-up tests, no cypress yet

* make i18n getDataRoute helper more DRY

* fix windows test

* add documentation for withoutProps and SSR pages logic for i18n

* clean up getStaticProps setup logic

* fix getStaticProps redirects logic to be consistent with setup and heavily comment

* fix revalidate redirects logic and heavily comment

* remove superfluous getDataRouteForI18nRoute helper

* remove superfluous getFilePathForRouteWithI18n helper

* fix existing cypress tests except a few v odd cases

* fix/move fallback i18n logic

* fix previously commented out failing dataRoute tests

* fix 404 cypress tests which expect root level 404.html

* specifically test i18n/non-default locales in cypress

* root level index pages need special dataRoute logic

* use splats for dynamic ssg i18n dataRoutes

* plain static routes need 2 redirects: one to defaultLocale, one to preview mode func

* massive cleanup/refactor to transform manifest

* missing initialProps + fallback logic + PR feedback
  • Loading branch information
lindsaylevine authored Jan 3, 2021
1 parent 55178a0 commit a2b9364
Show file tree
Hide file tree
Showing 50 changed files with 3,428 additions and 3,488 deletions.
2 changes: 1 addition & 1 deletion cypress/fixtures/next.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module.exports = {
target: "serverless",
target: "experimental-serverless-trace",
};
7 changes: 7 additions & 0 deletions cypress/fixtures/next.config.js-with-i18n
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
target: "experimental-serverless-trace",
i18n: {
locales: ["en", "fr"],
defaultLocale: "en"
}
};
12 changes: 12 additions & 0 deletions cypress/fixtures/pages-with-i18n/api/enterPreview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export default async function preview(req, res) {
const { query } = req;
const { id } = query;

// Enable Preview Mode by setting the cookies
res.setPreviewData({});

// Redirect to the path from the fetched post
// We don't redirect to req.query.slug as that might lead to open redirect vulnerabilities
res.writeHead(307, { Location: `/previewTest/${id}` });
res.end();
}
12 changes: 12 additions & 0 deletions cypress/fixtures/pages-with-i18n/api/enterPreviewStatic.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export default async function preview(req, res) {
const { query } = req;
const { id } = query;

// Enable Preview Mode by setting the cookies
res.setPreviewData({});

// Redirect to the path from the fetched post
// We don't redirect to req.query.slug as that might lead to open redirect vulnerabilities
res.writeHead(307, { Location: `/previewTest/static` });
res.end();
}
8 changes: 8 additions & 0 deletions cypress/fixtures/pages-with-i18n/api/exitPreview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export default async function exit(_, res) {
// Exit the current user from "Preview Mode". This function accepts no args.
res.clearPreviewData();

// Redirect the user back to the index page.
res.writeHead(307, { Location: "/" });
res.end();
}
6 changes: 6 additions & 0 deletions cypress/fixtures/pages-with-i18n/api/redirect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default async function preview(req, res) {
const { query } = req;
const { to } = query;

res.redirect(`/shows/${to}`);
}
23 changes: 23 additions & 0 deletions cypress/fixtures/pages-with-i18n/api/shows/[...params].js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export default async (req, res) => {
// Get the params and query string parameters
const { query } = req;
const { params, ...queryStringParams } = query;

// Get the ID of the show
const id = params[0];

// Get the data
const fetchRes = await fetch(`https://api.tvmaze.com/shows/${id}`);
const data = await fetchRes.json();

// If show was found, return it
if (fetchRes.status == 200) {
res.status(200);
res.json({ params, queryStringParams, show: data });
}
// If show was not found, return error
else {
res.status(404);
res.json({ error: "Show not found" });
}
};
20 changes: 20 additions & 0 deletions cypress/fixtures/pages-with-i18n/api/shows/[id].js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export default async (req, res) => {
// Get the ID of the show
const { query } = req;
const { id } = query;

// Get the data
const fetchRes = await fetch(`https://api.tvmaze.com/shows/${id}`);
const data = await fetchRes.json();

// If show was found, return it
if (fetchRes.status == 200) {
res.status(200);
res.json({ show: data });
}
// If show was not found, return error
else {
res.status(404);
res.json({ error: "Show not found" });
}
};
7 changes: 7 additions & 0 deletions cypress/fixtures/pages-with-i18n/api/static.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default (req, res) => {
// We can set custom headers
res.setHeader("My-Custom-Header", "header123");

res.status(200);
res.json({ message: "hello world :)" });
};
54 changes: 54 additions & 0 deletions cypress/fixtures/pages-with-i18n/getServerSideProps/[id].js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import Error from "next/error";
import Link from "next/link";

const Show = ({ errorCode, show }) => {
// If show item was not found, render 404 page
if (errorCode) {
return <Error statusCode={errorCode} />;
}

// Otherwise, render show
return (
<div>
<p>
This page uses getInitialProps() to fetch the show with the ID provided
in the URL: /shows/:id
<br />
Refresh the page to see server-side rendering in action.
<br />
You can also try changing the ID to any other number between 1-10000.
</p>

<hr />

<h1>Show #{show.id}</h1>
<p>{show.name}</p>

<hr />

<Link href="/">
<a>Go back home</a>
</Link>
</div>
);
};

export const getServerSideProps = async ({ params }) => {
// The ID to render
const { id } = params;

const res = await fetch(`https://api.tvmaze.com/shows/${id}`);
const data = await res.json();

// Set error code if show item could not be found
const errorCode = res.status > 200 ? res.status : false;

return {
props: {
errorCode,
show: data,
},
};
};

export default Show;
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import Error from "next/error";
import Link from "next/link";

const Show = ({ errorCode, show }) => {
// If show item was not found, render 404 page
if (errorCode) {
return <Error statusCode={errorCode} />;
}

// Otherwise, render show
return (
<div>
<p>
This page uses getInitialProps() to fetch the show with the ID provided
in the URL: /shows/:id
<br />
Refresh the page to see server-side rendering in action.
<br />
You can also try changing the ID to any other number between 1-10000.
</p>

<hr />

<h1>Show #{show.id}</h1>
<p>{show.name}</p>

<hr />

<Link href="/">
<a>Go back home</a>
</Link>
</div>
);
};

export const getServerSideProps = async ({ params }) => {
// The ID to render
const { slug } = params;
const id = slug[0];

const res = await fetch(`https://api.tvmaze.com/shows/${id}`);
const data = await res.json();

// Set error code if show item could not be found
const errorCode = res.status > 200 ? res.status : false;

return {
props: {
errorCode,
show: data,
},
};
};

export default Show;
38 changes: 38 additions & 0 deletions cypress/fixtures/pages-with-i18n/getServerSideProps/static.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import Link from "next/link";

const Show = ({ show }) => (
<div>
<p>
This page uses getInitialProps() to fetch the show with the ID provided in
the URL: /shows/:id
<br />
Refresh the page to see server-side rendering in action.
<br />
You can also try changing the ID to any other number between 1-10000.
</p>

<hr />

<h1>Show #{show.id}</h1>
<p>{show.name}</p>

<hr />

<Link href="/">
<a>Go back home</a>
</Link>
</div>
);

export const getServerSideProps = async ({ params }) => {
const res = await fetch("https://api.tvmaze.com/shows/42");
const data = await res.json();

return {
props: {
show: data,
},
};
};

export default Show;
43 changes: 43 additions & 0 deletions cypress/fixtures/pages-with-i18n/getStaticProps/[id].js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import Link from "next/link";

const Show = ({ show }) => (
<div>
<p>This page uses getStaticProps() to pre-fetch a TV show.</p>

<hr />

<h1>Show #{show.id}</h1>
<p>{show.name}</p>

<hr />

<Link href="/">
<a>Go back home</a>
</Link>
</div>
);

export async function getStaticPaths() {
// Set the paths we want to pre-render
const paths = [{ params: { id: "1" } }, { params: { id: "2" } }];

// We'll pre-render only these paths at build time.
// { fallback: false } means other routes should 404.
return { paths, fallback: false };
}

export async function getStaticProps({ params }) {
// The ID to render
const { id } = params;

const res = await fetch(`https://api.tvmaze.com/shows/${id}`);
const data = await res.json();

return {
props: {
show: data,
},
};
}

export default Show;
31 changes: 31 additions & 0 deletions cypress/fixtures/pages-with-i18n/getStaticProps/static.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import Link from "next/link";

const Show = ({ show }) => (
<div>
<p>This page uses getStaticProps() to pre-fetch a TV show.</p>

<hr />

<h1>Show #{show.id}</h1>
<p>{show.name}</p>

<hr />

<Link href="/">
<a>Go back home</a>
</Link>
</div>
);

export async function getStaticProps(context) {
const res = await fetch(`https://api.tvmaze.com/shows/71`);
const data = await res.json();

return {
props: {
show: data,
},
};
}

export default Show;
32 changes: 32 additions & 0 deletions cypress/fixtures/pages-with-i18n/getStaticProps/with-revalidate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import Link from "next/link";

const Show = ({ show }) => (
<div>
<p>This page uses getStaticProps() to pre-fetch a TV show.</p>

<hr />

<h1>Show #{show.id}</h1>
<p>{show.name}</p>

<hr />

<Link href="/">
<a>Go back home</a>
</Link>
</div>
);

export async function getStaticProps(context) {
const res = await fetch(`https://api.tvmaze.com/shows/71`);
const data = await res.json();

return {
props: {
show: data,
},
revalidate: 1,
};
}

export default Show;
Loading

0 comments on commit a2b9364

Please sign in to comment.