facebook / docusaurus

Easy to maintain open source documentation websites.
https://docusaurus.io
MIT License
56.67k stars 8.52k forks source link

Mobile Navbar and Sidebar buttons don't work on old mobile browsers #4748

Closed chetstone closed 3 years ago

chetstone commented 3 years ago

πŸ› Bug Report

When accessing docusaurus.io from an older phone, the navbar button in the top left doesn't do anything. Also, if a doc is loaded somehow, a button appears in the bottom right that is supposed to open the sidebar. It doesn't do anything.

Have you read the Contributing Guidelines on issues?

Yes

To Reproduce

Visit docusaurus.io on an iPhone 4s or a Simulated device running iOS 9.3

Expected behavior

The Hamburger menu at the top left in the navbar, when touched, should open an expanded navbar menu.

Also, if a Doc is visited, say by touching the Installation link in the footer, a Sidebar button should appear in the lower right of the screen. When touched, the sidebar menu should open

Actual Behavior

Neither of those buttons do anything when touched.

IMG_0001 IMG_0002

Your Environment

Reproducible Demo

Visit docusaurus.io with an old mobile browser. Unfortunately, I realize these are not readily available. Although one can purchase an iPhone 4S cheaply on eBay, Apple does not support simulators for iOS 9 on modern versions of MacOS/Xcode.

I'm using some old phones to test my app (and yes my app still supports iOS 9, because the iPhone 4S is the ideal size and shape for my app). The documentation I'm writing in docusaurus needs to appear in a WebView "help" screen in my app.

I also found similar though not identical issues when accessing docusaurus.io with a Samsung S5 running Android 6: Mozilla/5.0 (Linux; Android 6.0.1; SM-G900T Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/62.0.3202.84 Mobile Safari/537.36

I was able to work around this issue by upgrading Chrome and Android System Webview on the Samsung.

Unfortunately this workaround is not available on the iPhone: Safari cannot be upgraded independently of the OS and iOS 9.3.6 is the latest OS supported on this device.

slorber commented 3 years ago

Hi,

If the mobile items don't work, it is likely because the JS we send to the mobile browser use unsupported (too recent) JS syntax, and React fails to initialize. So you basically end up with a static website with only HTML/CSS, and no JS.

Docusaurus allows doc sites to define the list of supported browsers through some config: https://github.com/browserslist/browserslist

The config on our current website (in package.json) is:

  "browserslist": {
    "production": [
      ">0.5%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },

You can "eval" that config with the browserlist cli:

image

You can see that Safari 9 on iOS has 0.18% usage, which is very low. https://caniuse.com/usage-table

The more we add older browser support, the more we increase our site bundle size, penalizing all other users with increased site load times.

It is a tradeoff that we can choose for each Docusaurus site (apart from old browsers like IE11 that we plainly don't support).

In this case, I think it is on purpose that we don't support iOS 9 on Safari. We could, but do we really want to?

chetstone commented 3 years ago

No, I don’t think docusaurus.io needs to support it, but it’s cool that I should be able to support it on my own site. Thanks for the info.

On Fri, May 7, 2021 at 03:24 SΓ©bastien Lorber @.***> wrote:

Hi,

Docusaurus allows doc sites to define the list of supported browsers through some config: https://github.com/browserslist/browserslist

The config on our current website (in package.json) is:

"browserslist": { "production": [ ">0.5%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] },

You can "eval" that config with the browserlist cli:

[image: image] https://user-images.githubusercontent.com/749374/117428104-0906f100-af26-11eb-99ce-f0f045248b0e.png

You can see that Safari 9 on iOS has 0.18% usage, which is very low. https://caniuse.com/usage-table

The more we add older browser support, the more we increase our site bundle size, penalizing all other users with increased site load times.

It is a tradeoff that we can choose for each Docusaurus site (apart from old browsers like IE11 that we plainly don't support).

In this case, I think it is on purpose that we don't support iOS 9 on Safari. We could, but do we really want to?

β€” You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/facebook/docusaurus/issues/4748#issuecomment-834205967, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAHOLV2LHCVYXPZIYQPXADLTMOWVTANCNFSM44ITVFBA .

chetstone commented 3 years ago

It seems Safari 9 is just too old. After adding "ios_saf >= 9" to the browserlist spec, javascript fails with the error:

"Unexpected keyword 'const'. Const declarations are not supported in strict mode."

This error is coming from some packages in node_modules, because the docusaurus webpack configuration excludes node_modules from transpilation. I tried modifying the excludeJS function in the webpack config and managed to get those modules transpiled and that error went away, but then I got:

TypeError: Object.entries is not a function. (In 'Object.entries(_generated_routesChunkNames__WEBPACK_IMPORTED_MODULE_0__)', 'Object.entries' is undefined)
getChunkNamesToLoad
(anonymous function)
map
prefetch
(anonymous function)
invokePassiveEffectCreate
callCallback
dispatchEvent
invokeGuardedCallbackDev
invokeGuardedCallback
flushPassiveEffectsImpl
unstable_runWithPriority
runWithPriority$1
flushPassiveEffects
performSyncWorkOnRoot
performSyncWorkOnRoot
(anonymous function)
unstable_runWithPriority
runWithPriority$1
flushSyncCallbackQueueImpl
flushSyncCallbackQueue
unbatchedUpdates
legacyRenderSubtreeIntoContainer
render
(anonymous function)
promiseReactionJob

and

The above error occurred in the <Link> component:
Link
Logo
div
div
nav
Navbar
DocsPreferredVersionContextProviderUnsafe
DocsPreferredVersionContextProvider
UserPreferencesProvider
ThemeProvider
LayoutProviders
Layout
Home
Component
Component
Component
Component
Component
withRouter(PendingNavigation)
Root
App
Component
call@[native code]
chetstone commented 3 years ago

So webpack itself is emitting code that doesn't honor browserslist.

I tried uncommenting this line in the webpack config to try to get it to honor browserslist, and added a browserslist spec to the nearest package.json, but that didn't help.

slorber commented 3 years ago

@chetstone it's hard to help you figuring things out without seeing your site.

Docusaurus run Webpack + Babel with browserslist on its theme code and your site code, but it does not run it for third party libs (for perf reasons).

If a lib you use publish JS code that is not compatible with older browsers, you'd have to wire some transpilation for that lib yourself. Some libs are indeed using modern syntax and authors don't plan to do anything about that (for example, most libs from Sindre Sorhus)

Not sure why Object.entries is not polyfilled, can't tell you

chetstone commented 3 years ago

Sebastien,

Thanks for following up. I'm pretty sure you should be able to replicate this problem using the default site that is created when you initialize docusaurus. I have made only trivial changes (e.g. sidebar). The only library I added is react-device-detect, and that doesn't seem to be a problem. The two libraries I found using const were ansi-regex and strip-ansi. They are dependencies of some webpack and docusaurus libs (See below).

Object.entries appears to be code that is emitted by webpack itself. It could be a bug in webpack that it is not respecting browserlist.

I imagine the problem replicating my work is more finding an old browser. ( I had to boot from an old hard drive with El Capitan and Safari 11 on it so I could debug my phone's browser remotely). I tried to find an easier way to replicate, so I used Firefox 35.0b8. It is pretty easy to download old Firefoxes. Object.entries is supported starting in Firefox 36. I was hoping it would fail in the same place, but it actually fails earlier, and I don't remember that error right now.


yarn why v1.22.4
[1/4] πŸ€”  Why do we have the module "ansi-regex"...?
[2/4] 🚚  Initialising dependency graph...
[3/4] πŸ”  Finding dependency...
[4/4] 🚑  Calculating file sizes...
=> Found "ansi-regex@5.0.0"
info Reasons this module exists
   - "strip-ansi" depends on it
   - Hoisted from "strip-ansi#ansi-regex"
info Disk size without dependencies: "20KB"
info Disk size with unique dependencies: "20KB"
info Disk size with transitive dependencies: "20KB"
info Number of shared dependencies: 0
=> Found "string-width#ansi-regex@4.1.0"
info Reasons this module exists
   - "string-width#strip-ansi" depends on it
   - Hoisted from "string-width#strip-ansi#ansi-regex"
info Disk size without dependencies: "16KB"
info Disk size with unique dependencies: "16KB"
info Disk size with transitive dependencies: "16KB"
info Number of shared dependencies: 0
=> Found "webpack-dev-server#ansi-regex@2.1.1"
info Reasons this module exists
   - "@docusaurus#core#webpack-dev-server#strip-ansi" depends on it
   - Hoisted from "@docusaurus#core#webpack-dev-server#strip-ansi#ansi-regex"
info Disk size without dependencies: "16KB"
info Disk size with unique dependencies: "16KB"
info Disk size with transitive dependencies: "16KB"
info Number of shared dependencies: 0
=> Found "renderkid#ansi-regex@2.1.1"
info Reasons this module exists
   - "@docusaurus#core#html-webpack-plugin#pretty-error#renderkid#strip-ansi" depends on it
   - Hoisted from "@docusaurus#core#html-webpack-plugin#pretty-error#renderkid#strip-ansi#ansi-regex"
info Disk size without dependencies: "16KB"
info Disk size with unique dependencies: "16KB"
info Disk size with transitive dependencies: "16KB"
info Number of shared dependencies: 0
=> Found "cliui#ansi-regex@4.1.0"
info Reasons this module exists
   - "@docusaurus#core#webpack-dev-server#yargs#cliui#strip-ansi" depends on it
   - Hoisted from "@docusaurus#core#webpack-dev-server#yargs#cliui#strip-ansi#ansi-regex"
info Disk size without dependencies: "16KB"
info Disk size with unique dependencies: "16KB"
info Disk size with transitive dependencies: "16KB"
info Number of shared dependencies: 0
✨  Done in 0.61s.
(12:53:56/642)[Wonderful: docs]$ yarn why strip-ansi
yarn why v1.22.4
[1/4] πŸ€”  Why do we have the module "strip-ansi"...?
[2/4] 🚚  Initialising dependency graph...
[3/4] πŸ”  Finding dependency...
[4/4] 🚑  Calculating file sizes...
=> Found "strip-ansi@6.0.0"
info Has been hoisted to "strip-ansi"
info Reasons this module exists
   - Hoisted from "wrap-ansi#strip-ansi"
   - Hoisted from "@docusaurus#core#strip-ansi"
   - Hoisted from "@docusaurus#core#react-dev-utils#strip-ansi"
   - Hoisted from "wrap-ansi#string-width#strip-ansi"
   - Hoisted from "@docusaurus#core#boxen#string-width#strip-ansi"
   - Hoisted from "@docusaurus#core#boxen#widest-line#string-width#strip-ansi"
info Disk size without dependencies: "20KB"
info Disk size with unique dependencies: "40KB"
info Disk size with transitive dependencies: "40KB"
info Number of shared dependencies: 1
=> Found "string-width#strip-ansi@5.2.0"
info This module exists because "string-width" depends on it.
info Disk size without dependencies: "20KB"
info Disk size with unique dependencies: "40KB"
info Disk size with transitive dependencies: "40KB"
info Number of shared dependencies: 1
=> Found "webpack-dev-server#strip-ansi@3.0.1"
info This module exists because "@docusaurus#core#webpack-dev-server" depends on it.
info Disk size without dependencies: "16KB"
info Disk size with unique dependencies: "36KB"
info Disk size with transitive dependencies: "36KB"
info Number of shared dependencies: 1
=> Found "renderkid#strip-ansi@3.0.1"
info This module exists because "@docusaurus#core#html-webpack-plugin#pretty-error#renderkid" depends on it.
info Disk size without dependencies: "16KB"
info Disk size with unique dependencies: "36KB"
info Disk size with transitive dependencies: "36KB"
info Number of shared dependencies: 1
=> Found "cliui#strip-ansi@5.2.0"
info Reasons this module exists
   - "@docusaurus#core#webpack-dev-server#yargs#cliui" depends on it
   - Hoisted from "@docusaurus#core#webpack-dev-server#yargs#cliui#wrap-ansi#strip-ansi"
info Disk size without dependencies: "20KB"
info Disk size with unique dependencies: "40KB"
info Disk size with transitive dependencies: "40KB"
info Number of shared dependencies: 1
✨  Done in 0.54s.

[1/4] πŸ€”  Why do we have the module "wrap-ansi"...?
[2/4] 🚚  Initialising dependency graph...
[3/4] πŸ”  Finding dependency...
[4/4] 🚑  Calculating file sizes...
=> Found "wrap-ansi@7.0.0"
info Has been hoisted to "wrap-ansi"
info Reasons this module exists
   - Hoisted from "@docusaurus#core#boxen#wrap-ansi"
   - Hoisted from "@docusaurus#core#webpackbar#wrap-ansi"
info Disk size without dependencies: "228KB"
info Disk size with unique dependencies: "328KB"
info Disk size with transitive dependencies: "520KB"
info Number of shared dependencies: 8
=> Found "cliui#wrap-ansi@5.1.0"
info This module exists because "@docusaurus#core#webpack-dev-server#yargs#cliui" depends on it.
info Disk size without dependencies: "20KB"
info Disk size with unique dependencies: "120KB"
info Disk size with transitive dependencies: "312KB"
info Number of shared dependencies: 8
✨  Done in 0.55s.
chetstone commented 3 years ago

Confirmed. Tried with a fresh installation of docusaurus@latest and I get the same errors with Firefox 35.0b8 that I get with my site.

slorber commented 3 years ago

Not 100% sure but I think browserslist only affect the emitted syntax (const vs var etc), not the DOM APIs used.

I thought our Babel setup automatically add polyfills for missing apis but not sure it's the case actually.

If you need to support older browsers, using https://polyfill.io/v3/ can help you add missing polyfills like object entries

roddc commented 2 years ago

I also have this problem on Chrome 70, I have added chrome >= 70 into the browserslist, but Uncaught ReferenceError: globalThis is not defined still occurs

slorber commented 2 years ago

@roddc afaik browserslist only impacts JS syntax and not APIs used

https://caniuse.com/?search=globalThis

globalThis is only available in Chrome 71 and we use it. I guess you are from China? You should find a way to upgrade, there are likely other things we don't support in Chrome 70, including some newer CSS syntax

voidmain commented 1 year ago

I'm new to Docusaurus and I've been trying to read through your docs on my iPhone. The mobile nav is completely broken. I'd be happy to open a new ticket, but I thought I would post here in case you all prefer to re-use existing tickets.

I'm on iOS 16.2.

Josh-Cena commented 1 year ago

@voidmain Feel free to open a new issue. iOS 16.2 Safari is not an old browser.

slorber commented 1 year ago

I'm new to Docusaurus and I've been trying to read through your docs on my iPhone. The mobile nav is completely broken. I'd be happy to open a new ticket, but I thought I would post here in case you all prefer to re-use existing tickets.

I'm on iOS 16.2.

that would really help to give us a screenshot @voidmain

voidmain commented 1 year ago

I haven't been able to reproduce it. I'll open a new ticket if it happens again.