Updating Title/Description of app in Google Search

Hi team,
I created a web app and deploy it using Render.
I did also bought a domain and manage to link the domain with the streamlit app.
I even managed to add google analytics into it.
The problem that I’m facing is that in google search the app’s title is Streamlit
and the description it says You need to enable JavaScript to run this app.
Like shown in the image below

Screenshot 2024-02-03 at 09.09.33

You can check the app : https://www.worldmarathonsplanner.com/
In google search type : site:www.worldmarathonsplanner.com

I did found almost no literature about this issue only this How to edit index.html?
but not sure if there are other solutions out there.

Does someone also experienced the same issue and actually managed to solve it? Thanks in advance.

Gerard

1 Like

Hi @Gerard_Martinez_Cane

Have you tried setting st.set_page_config(page_title="My App") for your app.

More info in the Docs:

Hello @Gerard_Martinez_Cane,

You could potentially use st.markdown to inject custom HTML into your app, including meta tags, although this is more of a hack and its effectiveness might be limited since these tags need to be in the head section to be most effective.

st.markdown("""
    <meta name="description" content="Your description here" />
""", unsafe_allow_html=True)

Kind Regards,
Sahir

P.S. Lets connect on LinkedIn!

1 Like

Thanks for the quick reply professor, appreciate it !! I actually use a similar command but still not seeing the desired behaviour
Screenshot 2024-02-03 at 21.54.42

1 Like

Ok ! Managed to find a solution that actually worked.
In essence I had to modify the index.html file in /venv/lib/python3.10/site-packages/streamlit/static/index.html using a function that actually modifies the title and the noscript text.

def modify_tag_content(tag_name, new_content):
    index_path = pathlib.Path(st.__file__).parent / "static" / "index.html"
    logging.info(f'editing {index_path}')
    soup = BeautifulSoup(index_path.read_text(), features="html.parser")
    
    target_tag = soup.find(tag_name)  # find the target tag

    if target_tag:  # if target tag exists
        target_tag.string = new_content  # modify the tag content
    else:  # if target tag doesn't exist, create a new one
        target_tag = soup.new_tag(tag_name)
        target_tag.string = new_content
        try:
            if tag_name in ['title', 'script', 'noscript'] and soup.head:
                soup.head.append(target_tag)
            elif soup.body:
                soup.body.append(target_tag)
        except AttributeError as e:
            print(f"Error when trying to append {tag_name} tag: {e}")
            return

    # Save the changes
    bck_index = index_path.with_suffix('.bck')
    if not bck_index.exists():
        shutil.copy(index_path, bck_index)  # keep a backup
    index_path.write_text(str(soup))

modify_tag_content('title', 'World Marathons Planner')
modify_tag_content('noscript', 'Best Marathon Planner ! Browse through the event selection and discover your next Marathon challenge. Also get specific and personalized training plans.')

Final result.
Probably there is a better solution out there, but at least this one worked on my side

Screenshot 2024-02-04 at 22.07.41

Thanks once again to those who answer before, appreciate it

3 Likes

Great job in coming up with a working solution @Gerard_Martinez_Cane and great idea @sahirmaharaj

3 Likes

Have you found a way to make this work for the favicon as well? I know the only other way to do this is to change the streamlit index.html file located within the site-packages but this is difficult to do especially for those who do not have complete control over their requirement.txt files i.e deployment through Heroku in my case.

1 Like

Also wondering

I love this workaround, @Gerard_Martinez_Cane!

@Rafal_Pakoca, @POP, regarding the favion, have you tried this:

modify_tag_content('link', None, 'rel', 'icon', 'href', 'https://example.com/favicon.ico')

Best,
Charly

@Charly_Wargnier Yes, here is a snippet of my code that I modified from @Gerard_Martinez_Cane example above.

def modify_tag_content(tag_name, new_content, favicon_filename='FaviconIconUpdated-ts1695318835.svg'):
    index_path = pathlib.Path(st.__file__).parent / "static" / "index.html"
    logging.info(f'editing {index_path}')
    soup = BeautifulSoup(index_path.read_text(), features="html.parser")

    if tag_name == 'link' and 'rel' in new_content.lower() and 'icon' in new_content.lower():
        # Modify or add favicon link tag
        favicon_tag = soup.find('link', {'rel': 'icon'})
        if favicon_tag:
            favicon_tag['href'] = favicon_filename
        else:
            favicon_tag = soup.new_tag('link', rel='icon', type='image/svg+xml', href=favicon_filename)
            if soup.head:
                soup.head.append(favicon_tag)
    else:
        target_tag = soup.find(tag_name)  # find the target tag

        if target_tag:  # if target tag exists
            target_tag.string = new_content  # modify the tag content
        else:  # if target tag doesn't exist, create a new one
            target_tag = soup.new_tag(tag_name)
            target_tag.string = new_content
            try:
                if tag_name in ['title', 'script', 'noscript'] and soup.head:
                    soup.head.append(target_tag)
                elif soup.body:
                    soup.body.append(target_tag)
            except AttributeError as e:
                print(f"Error when trying to append {tag_name} tag: {e}")
                return

    # Save the changes
    bck_index = index_path.with_suffix('.bck')
    if not bck_index.exists():
        shutil.copy(index_path, bck_index)  # keep a backup
    index_path.write_text(str(soup))

# Example usage with modifying the title and favicon
modify_tag_content('title', 'POP • Live Stock Quotes')
modify_tag_content('noscript', 'Best Stock Quotes ! Browse Thousands of Stocks For Free.')
modify_tag_content('link', '', favicon_filename='FaviconIconUpdated-ts1695318835.svg')

This updates the contents correctly but this is only a temporary solution however, when the app session refreshes the favicon reverts back to the original streamlit favicon and then back to my favicon. This doesn’t look the greatest in Google search and I am unable to change the index.html file since I am deploying from Heroku. I wish Streamlit would make an easier & more universal solution for customizable favicons and app titles. Maybe this can be a .toml addition in the future.

Interesting suggestion to add these in the TOML file. We’ll take good note :+1:

Best,
Charly

1 Like

Thanks for the code Could you let me know where do you place this piece of code in your program.

Hi @Subha

There’s currently no native solution for this in Streamlit Cloud.

I haven’t tried this myself, but you might want to check out @POP’s suggestion mentioned above.

Hope this helps!

Best,
Charly

Thanks . Was wondering where to place the code, since I was using docker. Figured out that I can add command for running this function ,before running the streamlit app.

That’s wonderful news, @Subha! :hugs:

If possible, of course, could you please share this information here so it benefits our community? :blush:

Thanks in advance,
Charly

Sure.
Dockerfile looks somethng like this:

RUN pip install -r requirements.txt
RUN python modify_tag_content.py
ENTRYPOINT [“streamlit”, “run”]
CMD [ “app.py” ]

The key is that the modify_tag_content function is run before the streamlit app.
Hope this helps.

Wow, this is cool, I’d need to try it! Thanks for sharing! :hugs:

Charly