Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
783 views
in Technique[技术] by (71.8m points)

next.js - getStaticPath and the need for filetype in the URL

In /pages I have [page].js and index.js.

[page].js generate needed Pages by the Value of "CustomPage". It's content comes from an Data-JSON-File.

It work like expected, as long as I start on the Homepage and use links inside of my Webpage. For example I have 2 Pages for now: /impressum and /datenschutz.

So clicking the link "Impressum" open myDomain.com/impressum (and it work, BUT notice, there is no .html at the end). BUT, if I refresh the page, or type myDomain.com/impressum directly in the addressbar of the browser, I got an not found error (from nginx-server, not from next!).

Second try

As I need a fully static page and I've added getStaticPath and getStaticProps in the file for testing purposes, so that "real" html-files will be created:

import { useRouter } from 'next/router';

import Index from './index';
import config from '../content/config.yml';
import CustomPage from '../src/components/CustomPage';

const RoutingPage = () => {
  const { customPages } = config;
  const router = useRouter();
  const { page } = router.query;

  const findMatches = (requestedPage) =>
    customPages.find((customPage) => customPage.name === requestedPage) ||
    false;

  const customPageData = findMatches(page);
  if (customPageData !== false) {
    return <CustomPage pageContext={customPageData} />;
  }

  return page === 'index' ? (
    <Index page={page} />
  ) : (
    <p style={{ marginTop: '250px' }}>whats up {page}</p>
  );
};

export async function getStaticPaths() {
  return {
    paths: [
      { params: { page: 'impressum' } },
      { params: { page: 'datenschutz' } },
    ],
    fallback: false, // See the "fallback" section below
  };
}

export async function getStaticProps({ params }) {
  return { props: { page: params.page } };
}

export default RoutingPage;

This generates the single pages as real html-files: enter image description here

But this lead me to the next issue: I've implemented internal Links in the Webpage like this: enter image description here

which still lead a user to myDomain.com/impressum, now additionally there is myDomain.com/impressum.html available. From SEO perspective, this are two different paths.

How do I get them unified, so that I have only one path - regardles of whether if I open it from within my Webpage, or enter it directly.

Workaround Idea (??)

Sure, I could everywhere use something like:

<Link href={`/${item.page}.html`}>

But this only work if the Page is exported and copied to the Server. For next dev and next start this won't work, because the .html-File don't exist.... and so I'll lost the "page preview" while working at the page.

So only Idea I have is to set an ENV-Variable for .env.development & .env.production and encapsulate the -Component from NEXT in a HOC. In that HOC I could check if I'm currently in dev or prod and don't use .html for those links... otherwise add the .html to the link.

What YOU say about this. Do you have any other solution?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I don't know if it's state of the art, but as little workaround I did this:

I place the next/link-Component in a HOC and check if it's run on development or production (process.env.NODE_ENV):

import React from 'react';
import Link from 'next/link';

const LinkHoc = (props) => {
  const { as, href, children } = props;
  if (process.env.NODE_ENV === 'production') {
    return (
      <Link
        {...props}
        as={as ? `${as}.html` : ''}
        href={href ? `${href}.html` : ''}
      />
    );
  }
  return <Link {...props}>{children}</Link>;
};
export default LinkHoc;

With this workaround you get mydomain.com/impressum links in DEV and mydomain.com/impressum.html in production.

Only thing what to do at least is to rename the JSON-Files for the generated pages. They are in /out/_next/data/XYZranadomString/. They are named like impressum.json and you need to rename it to impressum.html.json to fix the 404 error on clientside for this files.

Would love to see a better Solution, so if you have any suggestions, please let me know!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...