Docusaurus: useLogo hook does not update on theme change

Created on 23 Apr 2020  路  6Comments  路  Source: facebook/docusaurus

馃悰 Bug Report

When using the useLogo hook provided by theme-classic in a custom page, the associated attributes do not update following a chance between dark/light themes.

Have you read the Contributing Guidelines on issues?

:+1:

To Reproduce

  1. Create a custom page with the following minimal content:
import React from 'react';
import Layout from '@theme/Layout';
import useLogo from '@theme/hooks/useLogo';

function LogoTest() {
  const {logoImageUrl} = useLogo();

  return (
    <Layout title="LogoTest">
      <img src={logoImageUrl} />
    </Layout>
    );
}

export default LogoTest;
  1. Ensure both navbar.logo.src and navbar.logo.srcDark are set in the config.

  2. Build + load in browser.

  3. Toggle theme light/dark state.

Expected behavior

src attribute should change between src and srcDark values.

Actual Behavior

src remains on original value.

Your Environment

  • Docusaurus version used: v2.0.0-alpha.50
  • Environment name and version (e.g. Chrome 78.0.3904.108, Node.js 10.17.0): FF 72.0.2
  • Operating system and version (desktop or mobile): NixOS (linux)

Reproducible Demo

See above.

bug

All 6 comments

We have not documented this hook, so it is not intended to be used by end-users.
But if you want this hook to work, you need to use state of isClient, as shown below.

https://github.com/facebook/docusaurus/blob/409f8788dc36842679ae6f16558c7c42ee09ccd1/packages/docusaurus-theme-classic/src/theme/Navbar/index.js#L172

Awesome. Thanks for looking into this.

After putting that into the test case unfortunately the behavior is the same.

import React from 'react';
import Layout from '@theme/Layout';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import useLogo from '@theme/hooks/useLogo';

function LogoTest() {
  const {isClient} = useDocusaurusContext();
  const {logoImageUrl} = useLogo();

  return (
    <Layout title="LogoTest">
      <img key={isClient} src={logoImageUrl} />
    </Layout>
    );
}

export default LogoTest;

Indeed it is, even useThemeContext does not work in pages.
@yangshun any ideas on this?

I'm still building up my mental model of this project, but in case it's of relevance pulling isDarkTheme directly from useTheme does work, but only on initial page load.

After some investigation, I found the reason.

First, you should not use useTheme(). It's designed to be used internally by useThemeContext(). You should use useThemeContext() instead. useLogo is fine since it calls useThemeContext() under the hood.

useThemeContext(), as the name implies, must work under some context. The context is <ThemeProvider>, which is part of Layout. See https://github.com/facebook/docusaurus/blob/d391a2bcdbe7d5096d08be88d8bf5467e70264a8/packages/docusaurus-theme-classic/src/theme/Layout/index.js#L52.

In a page, you might have something like

import React from 'react';
import Layout from '@theme/Layout';

function Page() {
  return (
    <Layout title="Foo" description="bar">
      Baz
    </Layout>
  );
}

export default Page;

If you try to useLogo, it might become:

import React from 'react';
import Layout from '@theme/Layout';

function Page() {
  // oops, use the ThemeProvider without being its child.
  const logo = useLogo();

  return (
    <Layout title="Foo" description="bar">
      Baz
    </Layout>
  );
}

export default Page;

A workaround is to move the content of the page to another component:

import React from 'react';
import Layout from '@theme/Layout';

function Content() {
  const logo = useLogo();
  return logo;
}

function Page() {
  return (
    <Layout title="Foo" description="bar">
      <Content />
    </Layout>
  );
}

export default Page;

Since we removed the useLogo hook (see #3730), this issue is no longer relevant, so I'm closing it.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

JoelMarcey picture JoelMarcey  路  3Comments

chandankumar4 picture chandankumar4  路  3Comments

sebqq picture sebqq  路  3Comments

lex111 picture lex111  路  3Comments

ericnakagawa picture ericnakagawa  路  3Comments