reactjsazurebing-apiscript-tagbing-search

Implementing Bing Custom Search HostedUI script element in a specific react component


I'm new to web dev, and first time poster...

I'm trying to use the Bing Custom Search HostedUI (I was hoping to not have to use the Web API) inside of a React component so that it is placed in a specific position. I don't want to use dangerouslySetInnerHtml because I've read that it is bad practice.

I've already set up the custom search instance and everything works fine when I use the script tag inside of the index.html file (besides not being where I want it to be). However, when I try to implement the script tag within the react component, it shows this error:

Script error. at handleError (http://localhost:3000/static/js/bundle.js:51198:58) at http://localhost:3000/static/js/bundle.js:51217:7

I've tried multiple methods including using react-helmet, using useEffect to change the DOM, and using the use-script package.

Using react-helmet

import React from 'react'
import { Helmet } from "react-helmet"

function ContainBrowseResults() {
  
    return (
    <div>
  
    <Helmet>
        <script type="text/javascript" 
            id="bcs_js_snippet"
            src="https://ui.customsearch.ai/api/ux/rendering-js?customConfig=<config-number>&market=en-US&version=latest&q=">
            async
        </script>
    </Helmet>

    </div>
  )
}

Using useEffect to insert into DOM (I think this might be way off target now that I think about it)

// useScript.ts

import { useEffect } from 'react';

const useScript = (type:string, id:string, src:string) => {

  useEffect(() => {
    const script = document.createElement('script');

    script.type=type;
    script.id=id;
    script.src = src;
    script.async = false;

    document.body.appendChild(script);

    return () => {
      document.body.removeChild(script);
    }
  }, [src]);
};

export default useScript;
//ContainBrowseResults.tsx

import React from 'react'
import useScript from '../../hooks/useScript'

function ContainBrowseResults() {

    useScript("text/javascript", "bcs_js_snippet", "https://ui.customsearch.ai/api/ux/rendering-js?customConfig=<config-number>&market=en-US&version=latest&q=")
  
    return (
    <div></div>
  )
}

export default ContainBrowseResults

Using the use-script

import React from 'react'
// import useScript from '../../hooks/useScript'
import useScript, { ScriptStatus } from '@charlietango/use-script'


function ContainBrowseResults() {

    const [ready, status] = useScript("https://ui.customsearch.ai/api/ux/rendering-js?customConfig=<config-number>=en-US&version=latest&q=")
    if (status === ScriptStatus.ERROR) {
      return <div>Failed to load API</div>
    }

    return (
    <div className='ContainBrowseResults'>
        {ready}
    </div>
  )
}

export default ContainBrowseResults

I expected these to render the Bing Custom Search HostedUI (search bar and search results) inside of the ContainBrowseResults component (in between my Header and Footer).

Any help would be greatly appreciated!


Solution

  • You shouldn't be trying to add a script tag through a React component. They're meant to be executed upon page load, not when a component is mounted.

    From the sounds of your question, it sounds like you want to load an external webpage within your web app. Have a look at using iframes for your case. After reading the docs on Hosted UI you should have a visitable link along with this <script /> element that you're trying to use. You should be able to do something like:

    function ContainBrowseResults() {
      // Remember to replace YOUR-CUSTOM-CONFIG-ID with your own id
      return (
        <div>
          <iframe
            src="https://ui.customsearch.ai/hosted?customConfig=YOUR-CUSTOM-CONFIG-ID"
            title="YOUR_SEARCH_BOX"
          >
          </iframe>
        </div>
      )
    }
    

    Docs for reference: https://learn.microsoft.com/en-us/azure/cognitive-services/bing-custom-search/hosted-ui