我需要getInitialProps
才能在呈现页面时立即运行服务器端,但是看来它只能在我的项目中页面的第一次呈现时运行。随后的每个渲染(例如,我跟随链接或通过Router.push(
\ link )
推送新路线),仅在客户端运行,而我无权访问在服务器端定义的ENV变量,例如我的GraphQL API_URL。
这是我的项目结构。
./pages
_app.tsx
index.tsx
other.tsx
在_app.tsx
中,我有以下内容
class CustomApp extends App {
static async getInitialProps({ Component, ctx }: AppContext) {
let pageProps = {};
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx);
}
return { pageProps };
}
render() {
const { Component, pageProps } = this.props;
return (
<>
<Head>
<title>My cool app</title>
</Head>
<Component {...pageProps} />
</>
);
}
}
export default CustomApp;
在index.tsx
import React, { Component } from 'react';
import Router from 'next/router';
class Index extends Component {
navigateToApplication = () => {
Router.push('/other');
};
render() {
return (
<div style={{width:100px, height:20px, color:red}} onClick={this.navigateToApplication}>
Click me!
</div>
);
}
}
export default Index;
在other.tsx
中,我有以下内容:
import React, { Component } from 'react';
import dynamic from 'next/dynamic';
import config from '../src/config';
//Ensure the WizardComponent loads CLIENT SIDE. This makes the 'fetch' utility available for the gqlClient
const WizardComponent = dynamic(() => import('../src/components/layout/WizardComponent'), { ssr: false });
class Application extends Component {
static async getInitialProps() {
return { config };
}
render() {
return <ApplicationWizard apiUrl={config.API_URL} />;
}
}
export default Application;
在config.ts
中,以下内容:
import getConfig from 'next/config';
const nextConfig = getConfig();
const clientConfig = (nextConfig && nextConfig.publicRuntimeConfigå) || {};
const settings = Object.keys(process.env).length > 1 ? process.env : clientConfig;
const config = new (class {
constructor(private readonly settings: Record<string, string | undefined>) {
console.log('getting details', settings);
console.log('NODE_ENV', this.settings['NODE_ENV']);
console.log('API_URL', this.settings['API_URL']);
}
readonly ENVIRONMENT = process.env.ENVIRONMENT || this.settings['NODE_ENV'] || 'development';
readonly API_URL = process.env.API_URL || this.settings['API_URL'] || 'http://localhost:4000/graphql';
})(settings);
export default config;
在next.config.js
中,我有以下内容:
const pick = require('lodash/pick');
const withCSS = require('@zeit/next-css');
const withSass = require('@zeit/next-sass');
const withPlugins = require('next-compose-plugins');
const withGraphql = require('next-plugin-graphql');
const path = require('path');
const nextConfig = {
webpack: (config, options) => {
config.resolve.alias['src'] = path.join(__dirname, 'src/');
return config;
}
,publicRuntimeConfig : pick(process.env, ['NODE_ENV', 'API_URL'])
};
module.exports = withPlugins([withCSS, withSass, withGraphql], nextConfig);
如果我直接访问http://host.url/other
,则getInitialProps
方法将按预期执行。如果我通过nextjs方法导航到页面,例如Router.push
或<Link>
HOC,然后env变量返回未定义,而我又退回到默认值...
我显然在这里缺少东西。请帮助!
我想做的就是在API_URL
页面上提供环境变量other.tsx
,无论我如何到达那里……