SJE is a custom Streamlit component, built to evaluate arbitrary Javascript expressions and return the result. It can become useful in doing certain functionalities which are simple things to do in JavaScript using the Web API, but unavailable or difficult to do in Streamlit. Examples include cookie management, writing to clipboard, getting device width (e.g. to check if we are on a mobile device), getting browser language, sharing something through Android’s share feature, knowing user agent, checking the battery and network status etc.
Here is an example
st.write(f"Screen width is {streamlit_js_eval(js_expressions='screen.width', key = 'SCR')}")
I will gradually add a more popular Web API to SJE in the form of Python functions so that the user does not have to see any JavaScript. Currently, we have Python wrapper for things like accessing cookies, the clipboard, and geolocation API. Here is an example of asking user’s location
# Returns user's location after asking for permission when the user clicks the generated link with the given text
location = get_geolocation()
Hope this very basic components helps other people and also make Streamlit even ore accessible, particularly with the recent emergence of Stlite, the great work of @whitphx to enable fully client-side Streamlit.
Sorry you ran into this. I don’t know much about the internals of callbacks in Streamlit and have not used them personally (or tested SJE against them).
As a quick fix, you can put the JS evaluation outside the callback function, like this:
import streamlit as st
from streamlit_js_eval import streamlit_js_eval
width = streamlit_js_eval(js_expressions='screen.width', want_output = True, key = 'SCR')
def disp_width():
to_display = f"Screen width is _{width}_"
print(to_display)
st.button("Display Screen Width", on_click=disp_width)
, which works on my machine. Does this fix work for you?
Thank you for the suggestion but I absolutelly need to get values from the localStorage many times from the code (using button callback).
If I look into the inspect console, I can see that the code tries to output the value but the value is not correctly received by the streamlit code. The error seems to be related to the reading of undefined properties.
Sorry, Marc. I played a bit with SJE source code and the issue is still there. It must have something to do with how callbacks work. I will create an issue in the Streamlit GitHub, but given that the components API is being rewritten, I am not sure there will be much effort on it
Can you tag someone from the Streamlit dev team here?
I tried this too and found it didn’t work using the callback. I also tried with a different JavaScript API component and encountered the same issue. So, it seems that components can’t be run within a widget callback.
This is an incredible component! I used it a few weeks ago in my app to get the latitude and longitude of my user. But now, it’s not working. I even tried the demo link multiple times, but the location feature isn’t returning any value. Please resolve this issue!
Hi. Sorry for the inconvenience. There has been no change in my code recently. Can you please confirm if it works on any other/older versions of Streamlit?
Thank you so much for the reply! I just tried it out on my phone and other laptop and it works just as perfectly as before. I believe there is an issue in my laptop. Thanks again, and sorry for the bother!
Hi @aghasemi,
thank you for your work and contribution.
I would like to ask you if I can implement an async javascript function inside the js_expressions argument and how to do it.
basically we receive data from an external authenticator system and I would like to fetch the attributes which are in the session page. Something like this:
async function getUser(){
const res = await fetch('myurl/Shibboleth.sso/Session')
const data = res.json()
document.getElementById("id").textContent = id}
This is the error logged in console: Uncaught SyntaxError: await is only valid in async functions and the top level bodies of modules at onDataFromPython
Great component! This provides a great workaround to dynamically sizing Altair combo charts, since use_container_width=True does not work with Altair combo charts.
Though streamlit_js_eval works great locally, when trying to run it on the streamlit cloud I get a ModuleNotFoundError even though I have listed it in my requirements.txt.
I am running streamlit v1.26.0 and streamlit_js_eval 0.1.5 locally, which I believe are the latest version. Does anyone have an idea why streamlit cloud can’t install the package even though it’s available in pip?
Thanks for this great component!
I’m thinking that it would be useful if I could add some more functionalities to this component, or maybe how to use it in “js_expressions” those api from the source that you have provided. This is more the state of js knowledge and creating new components, but if someone else is eager to showcase it that will be good for community to generate more functionalities.
In the Mdn web docs there is a lot of useful features.
Thanks for stopping by! We use cookies to help us understand how you interact with our website.
By clicking “Accept all”, you consent to our use of cookies. For more information, please see our privacy policy.
Cookie settings
Strictly necessary cookies
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
Performance cookies
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
Functional cookies
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
Targeting cookies
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.