javascript - Is there a cleaner way of getting current URL in both client and server side in isomorphic react apps? - Stack Over

I am developing an app based in this React Redux boilerplate. In one ponent I need to get the current

I am developing an app based in this React Redux boilerplate. In one ponent I need to get the current URL when ponent is mounted in order to generate a shareable URL for social media. Than ponent is being accesible from dynamically generated URLs with React Router. In client side I wouldn't have any problem by getting it through javascript document object but the problem lies server side.

I thought about making available in the Redux store the Node.js environment data kept in this config.js file, where hostname is kept

// Node.js environment file config.js    
require('babel-polyfill');

const environment = { 
  development: {
    isProduction: false
  },  
  production: {
    isProduction: true
  }
}[process.env.NODE_ENV || 'development'];

module.exports = Object.assign({
  host: process.env.HOST || 'localhost',
  port: process.env.PORT,
  apiHost: process.env.APIHOST || 'localhost',
  apiPort: process.env.APIPORT
}, environment);

and with the location object of React Router set as props in the ponent get the pathname and fully construct the URL.

What I have done is to create a simple reducer with an initial state to keep the Node.js config enviroment data and just the default action to include in my bineReducers function with the other app reducers.

const initialState = { 
  config: {}
};

export default function config(state = initialState, action = {}) {
  switch (action.type) {
    default:
      return state;
  }
}

And then I injected the Node.js object with the environment data in the creation of the store, as initial state data, in my server.js file.

import config from './config';
...
const store = createStore(memoryHistory, client, {config});
...

Thus I have available the hostname and I am able in the ponent to construct its full url both client and server side through Redux store.

But, is there any simpler / cleanest way? I am afraid I might be overkilling it or creating any security issue to my app.

I am developing an app based in this React Redux boilerplate. In one ponent I need to get the current URL when ponent is mounted in order to generate a shareable URL for social media. Than ponent is being accesible from dynamically generated URLs with React Router. In client side I wouldn't have any problem by getting it through javascript document object but the problem lies server side.

I thought about making available in the Redux store the Node.js environment data kept in this config.js file, where hostname is kept

// Node.js environment file config.js    
require('babel-polyfill');

const environment = { 
  development: {
    isProduction: false
  },  
  production: {
    isProduction: true
  }
}[process.env.NODE_ENV || 'development'];

module.exports = Object.assign({
  host: process.env.HOST || 'localhost',
  port: process.env.PORT,
  apiHost: process.env.APIHOST || 'localhost',
  apiPort: process.env.APIPORT
}, environment);

and with the location object of React Router set as props in the ponent get the pathname and fully construct the URL.

What I have done is to create a simple reducer with an initial state to keep the Node.js config enviroment data and just the default action to include in my bineReducers function with the other app reducers.

const initialState = { 
  config: {}
};

export default function config(state = initialState, action = {}) {
  switch (action.type) {
    default:
      return state;
  }
}

And then I injected the Node.js object with the environment data in the creation of the store, as initial state data, in my server.js file.

import config from './config';
...
const store = createStore(memoryHistory, client, {config});
...

Thus I have available the hostname and I am able in the ponent to construct its full url both client and server side through Redux store.

But, is there any simpler / cleanest way? I am afraid I might be overkilling it or creating any security issue to my app.

Share Improve this question edited Feb 13, 2018 at 15:20 Dez asked Mar 9, 2017 at 13:16 DezDez 5,8488 gold badges46 silver badges52 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 2

I was having this issue when attempting to use Helmet server-side. I passed in the request as a prop to my main <App> ponent and then use either that request object (server-side) or the window object (client-side).

App.js

render() {

    // Get full url from client or server
    let fullURL = ''
    if(typeof window !== 'undefined'){
        fullURL = window.location.protocol + '//' + window.location.host + this.props.location.pathname
    }else if(this.props.serverRequest){
        fullURL = this.props.serverRequest.headers.host + '/' + this.props.location.pathname
    }

    const urlTag = fullURL === '' ? null : <meta property="og:url" content={fullURL} />
    const linkTag = fullURL === '' ? null : <link rel="canonical" href={fullURL} />

    const helmet = this.props.siteInfo.site
        ? <Helmet>
            <title>{this.props.siteInfo.site.title}</title>
            <meta property="twitter:title" content={this.props.siteInfo.site.title} />
            {urlTag}
            {linkTag}
            <meta property="og:type" content="website" />
          </Helmet>
        : null

    return (
        <div>
            {helmet}
            <Notices />
            <div className="body">
                <Header />
                <Body />
            </div>
            <Footer />
        </div>
    )
}

server.js

const markup = renderToString(
    <Provider store={store}>
        <StaticRouter location={req.url} context={context}>
            <App serverRequest={req} />
        </StaticRouter>
    </Provider>
)

const helmet = Helmet.renderStatic()

Is this "proper" or "best practice"? No idea, but it works well and is easy to follow :)

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744725956a4590177.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信