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

Support for i18n in Next 10 #75

Merged
merged 22 commits into from
Jan 3, 2021
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
cc4de30
rough pass at i18n ssg breaking changes in next 10
lindsaylevine Nov 12, 2020
89b22e6
update withoutProps/redirects to accommodate defaultLocale
lindsaylevine Nov 29, 2020
7da18c2
very dirty Just Working i18n for most cases
lindsaylevine Dec 11, 2020
b475f4d
pre clean-up tests, no cypress yet
lindsaylevine Dec 11, 2020
c68d361
make i18n getDataRoute helper more DRY
lindsaylevine Dec 11, 2020
0c67c4b
fix windows test
lindsaylevine Dec 11, 2020
0498d83
add documentation for withoutProps and SSR pages logic for i18n
lindsaylevine Dec 12, 2020
c86eb09
clean up getStaticProps setup logic
lindsaylevine Dec 12, 2020
348705d
fix getStaticProps redirects logic to be consistent with setup and he…
lindsaylevine Dec 12, 2020
d45f240
fix revalidate redirects logic and heavily comment
lindsaylevine Dec 12, 2020
9609739
remove superfluous getDataRouteForI18nRoute helper
lindsaylevine Dec 12, 2020
fb11d14
remove superfluous getFilePathForRouteWithI18n helper
lindsaylevine Dec 12, 2020
90856ad
fix existing cypress tests except a few v odd cases
lindsaylevine Dec 16, 2020
acc13c9
fix/move fallback i18n logic
lindsaylevine Dec 17, 2020
db05c51
fix previously commented out failing dataRoute tests
lindsaylevine Dec 19, 2020
2d5e867
fix 404 cypress tests which expect root level 404.html
lindsaylevine Dec 19, 2020
04d57b4
specifically test i18n/non-default locales in cypress
lindsaylevine Dec 20, 2020
60e8a49
root level index pages need special dataRoute logic
lindsaylevine Dec 20, 2020
0d45036
use splats for dynamic ssg i18n dataRoutes
lindsaylevine Dec 20, 2020
96959bd
plain static routes need 2 redirects: one to defaultLocale, one to pr…
lindsaylevine Dec 20, 2020
447426d
massive cleanup/refactor to transform manifest
lindsaylevine Dec 22, 2020
25ff5fe
missing initialProps + fallback logic + PR feedback
lindsaylevine Jan 3, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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",
lindsaylevine marked this conversation as resolved.
Show resolved Hide resolved
};
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