Fix CI build SSG timeouts
- Add backend request timeout to prevent hanging builds - Make getStaticProps resilient to API failures - Avoid build-time crawling for dynamic routes (blocking fallback) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -1,8 +1,11 @@
|
|||||||
import axios, { AxiosInstance, AxiosRequestConfig } from "axios";
|
import axios, { AxiosInstance, AxiosRequestConfig } from "axios";
|
||||||
import { getAccessTokenCookie } from "@utils/auth";
|
import { getAccessTokenCookie } from "@utils/auth";
|
||||||
|
|
||||||
|
const API_TIMEOUT_MS = 10000;
|
||||||
|
|
||||||
const axiosInstance: AxiosInstance = axios.create({
|
const axiosInstance: AxiosInstance = axios.create({
|
||||||
baseURL: process.env.NEXT_PUBLIC_API_URL,
|
baseURL: process.env.NEXT_PUBLIC_API_URL,
|
||||||
|
timeout: API_TIMEOUT_MS,
|
||||||
});
|
});
|
||||||
|
|
||||||
export enum APIPath {
|
export enum APIPath {
|
||||||
|
|||||||
+26
-29
@@ -14,14 +14,13 @@ interface InitialProps {
|
|||||||
|
|
||||||
const EventPage: NextPage<InitialProps> = ({ event }) => {
|
const EventPage: NextPage<InitialProps> = ({ event }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { id } = router.query;
|
|
||||||
|
|
||||||
if (router.isFallback) return <LoadingView />;
|
if (router.isFallback) return <LoadingView />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Head>
|
<Head>
|
||||||
<link rel="canonical" href={`${process.env.NEXT_PUBLIC_SITE_URL}/events/${id}`} />
|
<link rel="canonical" href={`${process.env.NEXT_PUBLIC_SITE_URL}/events/${event.id}`} />
|
||||||
</Head>
|
</Head>
|
||||||
<PageWrapper>
|
<PageWrapper>
|
||||||
<EventPageView event={event} />
|
<EventPageView event={event} />
|
||||||
@@ -30,36 +29,34 @@ const EventPage: NextPage<InitialProps> = ({ event }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getStaticPaths: GetStaticPaths = async () => {
|
export const getStaticPaths: GetStaticPaths = async () => ({
|
||||||
const allEvents = await EventApi.getEvents();
|
paths: [],
|
||||||
const paths = allEvents.map((e: Event) => ({
|
fallback: "blocking",
|
||||||
params: {
|
});
|
||||||
id: String(e.id),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
));
|
|
||||||
return {
|
|
||||||
paths,
|
|
||||||
fallback: true,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getStaticProps: GetStaticProps<InitialProps> = async ({ params }) => {
|
export const getStaticProps: GetStaticProps<InitialProps> = async ({ params }) => {
|
||||||
const { id } = params;
|
const id = Number(params?.id);
|
||||||
let notFound = false;
|
if (!id) {
|
||||||
let event: Event;
|
return {
|
||||||
try {
|
notFound: true,
|
||||||
event = await EventApi.getEvent(Number(id));
|
revalidate: 10,
|
||||||
} catch (err) {
|
};
|
||||||
notFound = true;
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const event = await EventApi.getEvent(id);
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
event,
|
||||||
|
},
|
||||||
|
revalidate: 10, // Required for deleting hidden pages
|
||||||
|
};
|
||||||
|
} catch {
|
||||||
|
return {
|
||||||
|
notFound: true,
|
||||||
|
revalidate: 10,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return {
|
|
||||||
props: {
|
|
||||||
event,
|
|
||||||
},
|
|
||||||
revalidate: 10, // Required for deleting hidden pages
|
|
||||||
notFound,
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default EventPage;
|
export default EventPage;
|
||||||
|
|||||||
+25
-29
@@ -14,14 +14,13 @@ interface InitialProps {
|
|||||||
|
|
||||||
const FeedPage: NextPage<InitialProps> = ({ post }) => {
|
const FeedPage: NextPage<InitialProps> = ({ post }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { id } = router.query;
|
|
||||||
|
|
||||||
if (router.isFallback) return <LoadingView />;
|
if (router.isFallback) return <LoadingView />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Head>
|
<Head>
|
||||||
<link rel="canonical" href={`${process.env.NEXT_PUBLIC_SITE_URL}/feed/${id}`} />
|
<link rel="canonical" href={`${process.env.NEXT_PUBLIC_SITE_URL}/feed/${post.id}`} />
|
||||||
</Head>
|
</Head>
|
||||||
<PageWrapper>
|
<PageWrapper>
|
||||||
<FeedPageView post={post} />
|
<FeedPageView post={post} />
|
||||||
@@ -30,37 +29,34 @@ const FeedPage: NextPage<InitialProps> = ({ post }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getStaticPaths: GetStaticPaths = async () => {
|
export const getStaticPaths: GetStaticPaths = async () => ({
|
||||||
const feed = await FeedApi.getFeed();
|
paths: [],
|
||||||
const paths = feed.map((post: Post) => ({
|
fallback: "blocking",
|
||||||
params: {
|
});
|
||||||
id: String(post.id),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
));
|
|
||||||
return {
|
|
||||||
paths,
|
|
||||||
fallback: true,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getStaticProps: GetStaticProps<InitialProps> = async ({ params }) => {
|
export const getStaticProps: GetStaticProps<InitialProps> = async ({ params }) => {
|
||||||
const { id } = params;
|
const id = Number(params?.id);
|
||||||
let notFound = false;
|
if (!id) {
|
||||||
let post: Post;
|
return {
|
||||||
try {
|
notFound: true,
|
||||||
post = await FeedApi.getPost(Number(id));
|
revalidate: 10,
|
||||||
} catch (err) {
|
};
|
||||||
notFound = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
try {
|
||||||
props: {
|
const post = await FeedApi.getPost(id);
|
||||||
post,
|
return {
|
||||||
},
|
props: {
|
||||||
revalidate: 10, // Required for deleting hidden pages
|
post,
|
||||||
notFound,
|
},
|
||||||
};
|
revalidate: 10, // Required for deleting hidden pages
|
||||||
|
};
|
||||||
|
} catch {
|
||||||
|
return {
|
||||||
|
notFound: true,
|
||||||
|
revalidate: 10,
|
||||||
|
};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FeedPage;
|
export default FeedPage;
|
||||||
|
|||||||
@@ -44,12 +44,15 @@ const InEnglishPage: NextPage<InitialProps> = ({ initialEvents, initialFeed }) =
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getStaticProps: GetStaticProps<InitialProps> = async () => {
|
export const getStaticProps: GetStaticProps<InitialProps> = async () => {
|
||||||
const initialEvents = await fetcher<Event[]>(eventApi);
|
const [eventsResult, feedResult] = await Promise.allSettled([
|
||||||
const initialFeed = await fetcher<Post[]>(feedApi);
|
fetcher<Event[]>(eventApi),
|
||||||
|
fetcher<Post[]>(feedApi),
|
||||||
|
]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
initialEvents,
|
initialEvents: eventsResult.status === "fulfilled" ? eventsResult.value : [],
|
||||||
initialFeed,
|
initialFeed: feedResult.status === "fulfilled" ? feedResult.value : [],
|
||||||
},
|
},
|
||||||
revalidate: 10,
|
revalidate: 10,
|
||||||
};
|
};
|
||||||
|
|||||||
+7
-4
@@ -43,12 +43,15 @@ const FrontPage: NextPage<InitialProps> = ({ initialEvents, initialFeed }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getStaticProps: GetStaticProps<InitialProps> = async () => {
|
export const getStaticProps: GetStaticProps<InitialProps> = async () => {
|
||||||
const initialEvents = fetcher<Event[]>(eventApi);
|
const [eventsResult, feedResult] = await Promise.allSettled([
|
||||||
const initialFeed = fetcher<Post[]>(feedApi);
|
fetcher<Event[]>(eventApi),
|
||||||
|
fetcher<Post[]>(feedApi),
|
||||||
|
]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
initialEvents: await initialEvents,
|
initialEvents: eventsResult.status === "fulfilled" ? eventsResult.value : [],
|
||||||
initialFeed: await initialFeed,
|
initialFeed: feedResult.status === "fulfilled" ? feedResult.value : [],
|
||||||
},
|
},
|
||||||
revalidate: 10,
|
revalidate: 10,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,9 +3,7 @@ import { NextPage, GetStaticProps } from "next";
|
|||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import Event from "@models/Event";
|
import Event from "@models/Event";
|
||||||
import EventApi from "@api/eventApi";
|
|
||||||
import Post from "@models/Feed";
|
import Post from "@models/Feed";
|
||||||
import FeedApi from "@api/feedApi";
|
|
||||||
import ActualPageView from "@views/ActualPage/ActualPageView";
|
import ActualPageView from "@views/ActualPage/ActualPageView";
|
||||||
import PageWrapper from "@views/common/PageWrapper";
|
import PageWrapper from "@views/common/PageWrapper";
|
||||||
import { fetcher, APIPath, API } from "@api/backend";
|
import { fetcher, APIPath, API } from "@api/backend";
|
||||||
@@ -40,12 +38,15 @@ const ActualPage: NextPage<InitialProps> = ({ initialEvents, initialFeed }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getStaticProps: GetStaticProps<InitialProps> = async () => {
|
export const getStaticProps: GetStaticProps<InitialProps> = async () => {
|
||||||
const initialEvents = await EventApi.getEvents();
|
const [eventsResult, feedResult] = await Promise.allSettled([
|
||||||
const initialFeed = await FeedApi.getFeed();
|
fetcher<Event[]>(eventApi),
|
||||||
|
fetcher<Post[]>(feedApi),
|
||||||
|
]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
initialEvents,
|
initialEvents: eventsResult.status === "fulfilled" ? eventsResult.value : [],
|
||||||
initialFeed,
|
initialFeed: feedResult.status === "fulfilled" ? feedResult.value : [],
|
||||||
},
|
},
|
||||||
revalidate: 10,
|
revalidate: 10,
|
||||||
};
|
};
|
||||||
|
|||||||
+25
-27
@@ -112,36 +112,34 @@ const SignUpPage: NextPage<InitialProps> = ({ initialForm }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getStaticPaths: GetStaticPaths = async () => {
|
export const getStaticPaths: GetStaticPaths = async () => ({
|
||||||
const allForms = await SignupApi.getForms();
|
paths: [],
|
||||||
const paths = allForms.map((e: SignupForm) => ({
|
fallback: "blocking",
|
||||||
params: {
|
});
|
||||||
id: String(e.id),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
));
|
|
||||||
return {
|
|
||||||
paths,
|
|
||||||
fallback: true,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getStaticProps: GetStaticProps<InitialProps> = async ({ params }) => {
|
export const getStaticProps: GetStaticProps<InitialProps> = async ({ params }) => {
|
||||||
const { id } = params;
|
const id = Number(params?.id);
|
||||||
let notFound = false;
|
if (!id) {
|
||||||
let initialForm: SignupForm;
|
return {
|
||||||
try {
|
notFound: true,
|
||||||
initialForm = await SignupApi.getForm(Number(id));
|
revalidate: 10,
|
||||||
} catch {
|
};
|
||||||
notFound = true;
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const initialForm = await SignupApi.getForm(id);
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
initialForm,
|
||||||
|
},
|
||||||
|
revalidate: 10, // Required for deleting hidden pages
|
||||||
|
};
|
||||||
|
} catch {
|
||||||
|
return {
|
||||||
|
notFound: true,
|
||||||
|
revalidate: 10,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return {
|
|
||||||
props: {
|
|
||||||
initialForm,
|
|
||||||
},
|
|
||||||
revalidate: 10, // Required for deleting hidden pages
|
|
||||||
notFound,
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SignUpPage;
|
export default SignUpPage;
|
||||||
|
|||||||
@@ -30,10 +30,13 @@ const CorporatePage: NextPage<InitialProps> = ({ initialJobAds }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getStaticProps: GetStaticProps<InitialProps> = async () => {
|
export const getStaticProps: GetStaticProps<InitialProps> = async () => {
|
||||||
const initialJobAds = await fetcher<JobAd[]>(jobAdApi);
|
const jobAdsResult = await Promise.allSettled([
|
||||||
|
fetcher<JobAd[]>(jobAdApi),
|
||||||
|
]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
initialJobAds,
|
initialJobAds: jobAdsResult[0].status === "fulfilled" ? jobAdsResult[0].value : [],
|
||||||
},
|
},
|
||||||
revalidate: 10,
|
revalidate: 10,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user