I am trying to figure out how to use <script> loading in an existing React app that uses React modules.
All external libraries in my app are loaded with a module loader , e.g :
import Module from /path/to/module;
My task is to incorporate google recaptcha which in all examples that I have seen uses
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>
method to load api.js script file. Is there a way to wrap loading into a module?
thanks, forgive me if the question is dumb, total React noob here.
UPDATE:
I can't use npm , its disabled in my world. But I may be able to leverage this bit from the package.
import ReCAPTCHA from "./recaptcha";
import makeAsyncScriptLoader from "react-async-script";
const callbackName = "onloadcallback";
const lang = typeof window !== "undefined" && (window.recaptchaOptions && window.recaptchaOptions.lang) ?
`&hl=${window.recaptchaOptions.lang}` :
"";
const URL = `https://www.google.com/recaptcha/api.js?onload=${callbackName}&render=explicit${lang}`;
const globalName = "grecaptcha";
export default makeAsyncScriptLoader(ReCAPTCHA, URL, {
callbackName,
globalName,
exposeFuncs: ["getValue", "getWidgetId", "reset", "execute"],
});
`
This is probably what you are looking for :
react-google-recaptcha npm package
Related
I am trying to include a leaflet package in my locally hosted website. The idea of the website is to allow the user to query for tweets from the Twitter API (the request is sent fro the HTML page to a NodeJs server running on express) and have these sent back and loaded in the leaflet map using a bounding box to place the marker. Since most tweets don't come with a geotag or bounding box information, I thought the next best thing would be to take the name of the location (e.g. London) stored in the tweet metadata and do a reverse geocoding to get the bounding box from the city/location name. To do this reverse geocoding I thought I would use a leaflet add-on called leaflet-geosearch, since the other common option of using the Google Maps API seem not to be free. I have tried now many ways of importing this package into my project, but all with no luck. The documentation shows that it can be loaded using
// import
import { OpenStreetMapProvider } from 'leaflet-geosearch';
// setup
const provider = new OpenStreetMapProvider();
// search
const results = await provider.search({ query: input.value });
So I tried to load it in this fashion in my HTML code inside of a tag as such:
<script type="module">
import { OpenStreetMapProvider } from 'leaflet-geosearch';
// setup
const provider = new OpenStreetMapProvider();
</script>
But it tells me that I need to add a '/' for a relative pathway. So I tried to load it using a relative path to numerous different scripts in the node_modules/leaflet-geosearch folder:
<script type="module">
import { OpenStreetMapProvider } from './node_modules/leaflet-geosearch/dist/geosearch.js';
// setup
const provider = new OpenStreetMapProvider();
</script>
The above method told me that "'geosearch.js' does not provide an export named 'OpenStreetMapProvider'", so I went back and looked through the files some more and found a file named 'openStreetMapProvider.js' and so tried to load this:
<script type="module">
import { OpenStreetMapProvider } from './node_modules/leaflet-geosearch/lib/providers/openStreetMapProvider.js';
// setup
const provider = new OpenStreetMapProvider();
</script>
But it gave me the same error "... does not provide an export named 'OpenStreetMapProvider'".
I have tried to load it directly into my nodeJS server script,
// import
const OpenStreetMapProvider = require('leaflet-geosearch');
// setup
const provider = new OpenStreetMapProvider();
But when I then try to run the server on a local port it throws the Reference error below.
Does anyone know how I could properly load and use this module in my HTML page? I have seen some answers that say browserify can help in such cases, but if that was really necessary then the ReadME on the package's github page should have mentioned this, so I feel like there must be a more straightforward solution to this.
I want to use imageToZ64() from zpl-image module
I have installed it using: npm install zpl-image
and then I import it: import './../../../node_modules/zpl-image';
but when I use the fucntion like this let res = imageToZ64(canvas);
i'm getting : Uncaught (in promise) ReferenceError: imageToZ64 is not defined
I tried to import it like this: import { imageToZ64 } from './../../../node_modules/zpl-image/zpl-image';
but the problem is this function uses other functions from pako.js which is another js file in the zpl-image.
my question is how to import the module in a way that I can be able to access all the functions?
I highly recommend you read the README here : zpl-image repo GitHub
In order to use this with Node.js :
const imageToZ64 = require("zpl-image").imageToZ64;
Or :
const { imageToZ64, rgbaToZ64 } = require("zpl-image");
If you are trying to use it in the browser read generic browser usage
since you already installed it via npm there is a demo file in node_modules/zpl-image/zpl-image.html ,you can open it in the browser, read its content, and understand how the code works which is the purpose of the demo file.
I'm trying to use the react-datepickermodule in my react App, but I'm having a hard time trying to load the css module of react-datepicker. I'm using next.js to render my app on server side.
I tried to implement a css loader provided by next to solve this kind of issue, but I got an error trying to build my app:
error
My component.js file:
import DatePicker from "react-datepicker";
import 'react-datepicker/dist/react-datepicker-cssmodules.css';
My nex.config.js file:
const withImages = require('next-images');
const withCSS = require('#zeit/next-css');
module.exports = withImages(
withCSS({
cssModules: true
})
);
Can you please tell me what is wrong with my imports or config ? Or what the 'minimize' property (displayed on the error message) means ?
Thanks a lot
EDIT: I ended up by importing css directly from
<link href="/static/react-datepicker.css" rel="stylesheet" />. Original post
Your css modules must end with .module.css.
To use CSS Modules, import a CSS file named *.module.css from any component. src
Import this way instead:
import styles from 'react-datepicker/dist/react-datepicker-min.module.css'
Try using Compose in your config file
I think you need to compose your plugins like so
// ... other imports
const compose = require('next-compose');
module.exports = compose([
withImages(),
withCss(),
{
webpack: (config) => {
/**some special code */
return config
}
}
]);
Details about the plugin can be found here
Your code is fine!
Instead of importing CSS into a component, try to import it into the page you wanted to use it on.
Next.js supports only custom page CSS imports.
I am working on a project that requires using a js plugin. Now that we're using vue and we have a component to handle the plugin based logic, I need to import the js plugin file within the vue component in order to initialize the plugin.
Previously, this was handled within the markup as follows:
<script src="//api.myplugincom/widget/mykey.js
"></script>
This is what I tried, but I am getting a compile time error:
MyComponent.vue
import Vue from 'vue';
import * from '//api.myplugincom/widget/mykey.js';
export default {
data: {
My question is, what is the proper way to import this javascript file so I can use it within my vue component?
...
Include an external JavaScript file
Try including your (external) JavaScript into the mounted hook of your Vue component.
<script>
export default {
mounted() {
const plugin = document.createElement("script");
plugin.setAttribute(
"src",
"//api.myplugincom/widget/mykey.js"
);
plugin.async = true;
document.head.appendChild(plugin);
}
};
</script>
Reference: How to include a tag on a Vue component
Import a local JavaScript file
In the case that you would like to import a local JavaScript in your Vue component, you can import it this way:
MyComponent.vue
<script>
import * as mykey from '../assets/js/mykey.js'
export default {
data() {
return {
message: `Hello ${mykey.MY_CONST}!` // Hello Vue.js!
}
}
}
</script>
Suppose your project structure looks like:
src
- assets
- js
- mykey.js
- components
MyComponent.vue
And you can export variables or functions in mykey.js:
export let myVariable = {};
export const MY_CONST = 'Vue.js';
export function myFoo(a, b) {
return a + b;
}
Note: checked with Vue.js version 2.6.10
try to download this script
import * from '{path}/mykey.js'.
or import script
<script src="//api.myplugincom/widget/mykey.js"></script>
in <head>, use global variable in your component.
For scripts you bring in the browser way (i.e., with tags), they generally make some variable available globally.
For these, you don't have to import anything. They'll just be available.
If you are using something like Webstorm (or any of the related JetBrains IDEs), you can add /* global globalValueHere */ to let it know that "hey, this isn't defined in my file, but it exists." It isn't required, but it'll make the "undefined" squiggly lines go away.
For example:
/* global Vue */
is what I use when I am pulling Vue down from a CDN (instead of using it directly).
Beyond that, you just use it as you normally would.
I wanted to embed a script on my component and tried everything mentioned above, but the script contains document.write. Then I found a short article on Medium about using postscribe which was an easy fix and resolved the matter.
npm i postscribe --save
Then I was able to go from there. I disabled the useless escape from eslint and used #gist as the template's single root element id:
import postscribe from 'postscribe';
export default {
name: "MyTemplate",
mounted: function() {
postscribe(
"#gist",
/* eslint-disable-next-line */
`<script src='...'><\/script>`
);
},
The article is here for reference:
https://medium.com/#gaute.meek/how-to-add-a-script-tag-in-a-vue-component-34f57b2fe9bd
For anyone including an external JS file and having trouble accessing the jQuery prototype method(s) inside of the loaded script.
Sample projects I saw in vanilla JS, React and Angular were simply using:
$("#someId").somePlugin(options)
or
window.$("#someId").somePlugin(options)
But when I try either of those in my VueJS component I receive:
Error: _webpack_provided_window_dot$(...).somePluginis not a function
I examined the window object after the resources had loaded I was able to find the jQuery prototype method in the window.self read-only property that returns the window itself:
window.self.$("#someId").somePlugin(options)
Many examples show how to load the external JS file in VueJS but not actually using the jQuery prototype methods within the component.
I'd like to import this javascript package in React
<script src="https://cdn.dwolla.com/1/dwolla.js"></script>
However, there is no NPM package, so I can't import it as such:
import dwolla from 'dwolla'
or
import dwolla from 'https://cdn.dwolla.com/1/dwolla.js'
so whenver I try
dwolla.configure(...)
I get an error saying that dwolla is undefined. How do I solve this?
Thanks
Go to the index.html file and import the script
<script src="https://cdn.dwolla.com/1/dwolla.js"></script>
Then, in the file where dwolla is being imported, set it to a variable
const dwolla = window.dwolla;
This question is getting older, but I found a nice way to approach this using the react-helmet library which I feel is more idiomatic to the way React works. I used it today to solve a problem similar to your Dwolla question:
import React from "react";
import Helmet from "react-helmet";
export class ExampleComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
myExternalLib: null
};
this.handleScriptInject = this.handleScriptInject.bind(this);
}
handleScriptInject({ scriptTags }) {
if (scriptTags) {
const scriptTag = scriptTags[0];
scriptTag.onload = () => {
// I don't really like referencing window.
console.log(`myExternalLib loaded!`, window.myExternalLib);
this.setState({
myExternalLib: window.myExternalLib
});
};
}
}
render() {
return (<div>
{/* Load the myExternalLib.js library. */}
<Helmet
script={[{ src: "https://someexternaldomain.com/myExternalLib.js" }]}
// Helmet doesn't support `onload` in script objects so we have to hack in our own
onChangeClientState={(newState, addedTags) => this.handleScriptInject(addedTags)}
/>
<div>
{this.state.myExternalLib !== null
? "We can display any UI/whatever depending on myExternalLib without worrying about null references and race conditions."
: "myExternalLib is loading..."}
</div>
</div>);
}
}
The use of this.state means that React will automatically be watching the value of myExternalLib and update the DOM appropriately.
Credit: https://github.com/nfl/react-helmet/issues/146#issuecomment-271552211
for typescript developers
const newWindowObject = window as any; // cast it with any type
let pushNotification = newWindowObject.OneSignal; // now OneSignal object will be accessible in typescript without error
You can't require or import modules from a URL.
ES6: import module from URL
What you can do is make an HTTP request to get the script content & execute it, as in the answer for how to require from URL in Node.js
But this would be a bad solution since your code compilation would depend on an external HTTP call.
A good solution would be to download the file into your codebase and import it from there.
You could commit the file to git if the file doesn't change much & are allowed to do it. Otherwise, a build step could download the file.
var _loaded = {};
function addScript(url) {
if (!loaded[url]) {
var s = document.createElement('script');
s.src = url;
document.head.appendChild(s);
_loaded[url] = true;
}
}
how to load javascript file from cdn server in a component
Add the script tag in your index.html and if you are using Webpack, you can use this webpack plugin https://webpack.js.org/plugins/provide-plugin/