{"id":21277657,"url":"https://github.com/supukarmin/env-hoc","last_synced_at":"2025-07-11T08:31:59.040Z","repository":{"id":57225894,"uuid":"119124480","full_name":"supukarmin/env-hoc","owner":"supukarmin","description":"Provides a universal HOC (higher-order component) for React and populates the component props with an env property, which gives access to cookies, language(s), userAgent and other variables on server-side and client-side in a standardized way.","archived":false,"fork":false,"pushed_at":"2023-03-01T14:16:57.000Z","size":589,"stargazers_count":7,"open_issues_count":5,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-17T17:47:26.229Z","etag":null,"topics":["afterjs","client","cookies","higher-order-component","hoc","ipaddress","languages","navigator","nextjs","server","universal","useragent"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/supukarmin.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-01-27T02:19:15.000Z","updated_at":"2024-10-16T20:04:07.000Z","dependencies_parsed_at":"2023-02-14T04:01:46.470Z","dependency_job_id":null,"html_url":"https://github.com/supukarmin/env-hoc","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/supukarmin%2Fenv-hoc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/supukarmin%2Fenv-hoc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/supukarmin%2Fenv-hoc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/supukarmin%2Fenv-hoc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/supukarmin","download_url":"https://codeload.github.com/supukarmin/env-hoc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225708290,"owners_count":17511635,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["afterjs","client","cookies","higher-order-component","hoc","ipaddress","languages","navigator","nextjs","server","universal","useragent"],"created_at":"2024-11-21T10:06:41.267Z","updated_at":"2024-11-21T10:06:41.740Z","avatar_url":"https://github.com/supukarmin.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# env-hoc (optimized for [Next.js](https://github.com/zeit/next.js) \u0026 [After.js](https://github.com/jaredpalmer/after.js))\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://github.com/facebook/react/blob/master/LICENSE) [![npm version](https://img.shields.io/npm/v/env-hoc.svg?style=flat-square)](https://www.npmjs.com/package/env-hoc) [![Coverage Status](https://img.shields.io/coveralls/supukarmin/env-hoc/master.svg?style=flat-square)](https://coveralls.io/github/supukarmin/env-hoc?branch=master) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://reactjs.org/docs/how-to-contribute.html#your-first-pull-request)\n\nProvides an **universal** [HOC (higher-order component)](https://reactjs.org/docs/higher-order-components.html) for React components and populates the component props and the getInitialProps args object with an env property, which gives ***access to cookies, language(s), userAgent and doNotTrack*** in a standardized way. If you are using [Next.js](https://github.com/zeit/next.js) / [After.js](https://github.com/jaredpalmer/after.js) you will get also access to the IP address and benefit heavily from the standardized API on ***server-side and client-side***.\n\n* **Save time:** Most important thing: short if-else-blocks, no formatting needed, no old-browser-carrying, etc.\n* **Standardized:** `Accept-Language` \u0026\u0026 `User-Agent` \u0026\u0026 `Cookie` \u0026\u0026 `DNT` headers are parsed and available in the same format as in `window`. (same parsing libraries / functions \u0026\u0026 reformatting \u0026\u0026 **backwards compatibility**)\n* **Access to IP address:** IP address is available client-side and there are checked 10+ properties to ensure you always get the best match. Supports enabling/disabling of proxy trusting.\n* **Fully tested:** Tested for strange edge cases, missing HTTP headers or missing window properties.\n* **Some nice to have features:**\n  * Console.warns() while process.ENV.NODE_ENV === 'development', if server props !== client props\n  * Possibility to only use props from the HTTP request\n\n![this.props.env](docs/res/envProps.png?raw=true \"this.props.env\")\n\n***Feature requests for additional properties are welcomed***\n\n# Install\nYou can install it directly from [npm](https://www.npmjs.com/package/env-hoc):\n```shell\nnpm i env-hoc\n```\nor, if you are using yarn:\n```shell\nyarn add env-hoc\n```\n\n# Usage\n\n## with [decorators](https://www.sitepoint.com/javascript-decorators-what-they-are/)\n\nJust import the package and add it as a decorator to every page where you want to have access to the `env` object.\n```js\nimport React from 'react';\nimport withEnv from 'env-hoc';\n\n@withEnv\nclass Environment extends React.Component {\n  //getInitialProps is a Next.js/After.js thing, just ignore it, if you aren't using one of them\n  static getInitialProps(args) {\n    console.log('args.env:', args.env);\n  }\n\n  render() {\n    console.log('this.props:', this.props.env);\n    return (\n      \u003cdiv\u003e\n        \u003ch1\u003eEnvironment\u003c/h1\u003e\n        \u003cpre\u003euserAgent: {this.props.env.userAgent}\u003c/pre\u003e\n        \u003cpre\u003elanguage: {this.props.env.language}\u003c/pre\u003e\n        \u003cpre\u003elanguages: {this.props.env.languages.join(', ')}\u003c/pre\u003e\n        \u003cpre\u003eipAddress: {this.props.env.ipAddress}\u003c/pre\u003e\n        \u003cpre\u003ecookies: {JSON.stringify(this.props.env.cookies)}\u003c/pre\u003e\n        \u003cpre\u003edoNotTrack: {this.props.env.doNotTrack ? 'true' : 'false'}\u003c/pre\u003e\n      \u003c/div\u003e\n    );\n  }\n}\n\nexport default Environment;\n```\n### console output\n```\n/* CONSOLE OUTPUT:\nargs.env: { userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',\n  language: 'de-DE',\n  languages: [ 'de-DE', 'de', 'en-US', 'en', 'bs', 'hr' ],\n  cookies: {},\n  doNotTrack: true,\n  ipAddress: '::1' }\nthis.props: { userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',\n  language: 'de-DE',\n  languages: [ 'de-DE', 'de', 'en-US', 'en', 'bs', 'hr' ],\n  cookies: {},\n  doNotTrack: true,\n  ipAddress: '::1' }\n*/\n```\n\n## without decorators\n\nJust import the package and wrap it around every page where you want to have access to the `env` object.\n```js\nimport React from 'react';\nimport withEnv from 'env-hoc';\n\nclass Environment extends React.Component {\n  //getInitialProps is a Next.js/After.js thing, just ignore it, if you aren't using one of them\n  static getInitialProps(args) {\n    console.log('args.env:', args.env);\n  }\n\n  render() {\n    console.log('this.props:', this.props.env);\n    return (\n      \u003cdiv\u003e\n        \u003ch1\u003eEnvironment\u003c/h1\u003e\n        \u003cpre\u003euserAgent: {this.props.env.userAgent}\u003c/pre\u003e\n        \u003cpre\u003elanguage: {this.props.env.language}\u003c/pre\u003e\n        \u003cpre\u003elanguages: {this.props.env.languages.join(', ')}\u003c/pre\u003e\n        \u003cpre\u003eipAddress: {this.props.env.ipAddress}\u003c/pre\u003e\n        \u003cpre\u003ecookies: {JSON.stringify(this.props.env.cookies)}\u003c/pre\u003e\n        \u003cpre\u003edoNotTrack: {this.props.env.doNotTrack ? 'true' : 'false'}\u003c/pre\u003e\n      \u003c/div\u003e\n    );\n  }\n}\n\nexport default withEnv(Environment);\n```\n\n## Example with options\n\n```js\n//without decorator\nwithEnv({\n  trustProxy: false,\n})(Environment);\n\n//with decorator\n@withEnv({\n  trustProxy: false,\n})\nclass Environment extends React.Component {}\n```\n\n### onetime configuration\nYou can also configure withEnv once in a file and then import it from there when needed.\n```js\n\n//file: configuredWithEnv.js\nexport default withEnv({\n  trustProxy: false,\n});\n\n//file: page.js\nimport configuredWithEnv from './configuredWithEnv';\n\n//with decorator\n@configuredWithEnv\nexport default class Environment extends React.Component {}\n\n//without decorator\nconfiguredWithEnv(class Environment extends React.Component {})\n```\n\n## Configuration / Options\n* **trustProxy:** (boolean) If true, then it trusts proxy HTTP headers.\n* **cookieParser:** (object) Is beeing passed to the parse function of the [cookie package](https://github.com/jshttp/cookie).\n* **debug:** (boolean) If true, then it console.warns() you about different client / server behaviour.\n* **useServerProps:** (boolean/object) If true, only the props from server-rendering are used. You can also pass an object with keys matching the key from this.props.env and enable usage of server props only partially. For example:\n```js\nwithEnv({\n    useServerProps: {\n      cookies: true,\n      languages: true,\n    },\n});\n```\n\n### Default options\n```js\nwithEnv({\n    trustProxy: true,\n    cookieParser: {},\n    debug: process.env.NODE_ENV === 'development',\n    useServerProps: false,\n});\n```\n\n### Some hints\nIf you want to be a good programmer or support very old browsers, you should still check if a property is available, if some data isn't available, then it will be always for:\n* all properties except cookies: `null`\n* cookies: `{}`\n\nSo a short `if () {}` will do it mostly.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsupukarmin%2Fenv-hoc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsupukarmin%2Fenv-hoc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsupukarmin%2Fenv-hoc/lists"}