1
00:00:03,000 --> 00:00:05,367
We're now reading the review text

2
00:00:05,367 --> 00:00:07,746
from a separate Markdown file.

3
00:00:07,746 --> 00:00:10,406
But the page is currently displaying

4
00:00:10,406 --> 00:00:12,179
the raw Markdown source.

5
00:00:12,253 --> 00:00:15,265
We can render it to HTML by using

6
00:00:15,265 --> 00:00:17,546
a library such as Marked.

7
00:00:17,638 --> 00:00:20,416
So, to begin with, let's go and install

8
00:00:20,416 --> 00:00:22,554
that library into our project.

9
00:00:22,625 --> 00:00:25,063
In the terminal, I'll stop the server,

10
00:00:25,225 --> 00:00:27,838
and run "npm install marked",

11
00:00:27,838 --> 00:00:30,344
that will download the right package.

12
00:00:30,344 --> 00:00:32,255
It's not always necessary to

13
00:00:32,255 --> 00:00:34,097
stop the server by the way,

14
00:00:34,166 --> 00:00:37,038
you could run "npm install" in a separate

15
00:00:37,038 --> 00:00:38,719
terminal if you want to,

16
00:00:38,790 --> 00:00:40,861
and leave the server running.

17
00:00:41,030 --> 00:00:44,261
Anyway, back to our StardewValleyPage.

18
00:00:44,261 --> 00:00:47,786
Here we can now import the "marked" function

19
00:00:47,786 --> 00:00:50,217
from the module we just installed.

20
00:00:51,446 --> 00:00:53,509
And we can use this function

21
00:00:53,509 --> 00:00:55,204
to render the Markdown.

22
00:00:55,277 --> 00:00:57,933
We'll get the resulting "html"

23
00:00:57,933 --> 00:00:59,703
by parsing the text.

24
00:00:59,792 --> 00:01:03,713
And at this point we can display the "html" here.

25
00:01:03,713 --> 00:01:05,771
If we go and reload the page,

26
00:01:06,293 --> 00:01:09,129
you can see that it's showing the HTML.

27
00:01:09,129 --> 00:01:12,233
However, this is actually the HTML code,

28
00:01:12,233 --> 00:01:14,018
including all the tags.

29
00:01:14,095 --> 00:01:17,183
That's because we put the "html" variable

30
00:01:17,183 --> 00:01:19,217
inside a paragraph element,

31
00:01:19,292 --> 00:01:21,805
and React will automatically escape

32
00:01:21,805 --> 00:01:23,456
any special characters,

33
00:01:23,528 --> 00:01:26,275
like the angle brackets in the tags.

34
00:01:26,275 --> 00:01:28,813
We'll see how to fix this in a second.

35
00:01:28,813 --> 00:01:31,765
But first, let's check the server logs.

36
00:01:31,765 --> 00:01:34,359
There are a couple of warnings here,

37
00:01:34,359 --> 00:01:36,088
from the marked library.

38
00:01:36,160 --> 00:01:39,687
It says there are some parameters, like "mangle",

39
00:01:39,687 --> 00:01:41,974
that are "enabled by default",

40
00:01:41,974 --> 00:01:43,575
but are "deprecated".

41
00:01:43,651 --> 00:01:45,111
That's a bit unusual.

42
00:01:45,111 --> 00:01:47,437
If they're deprecated then why

43
00:01:47,437 --> 00:01:49,607
are they enabled by default?

44
00:01:49,684 --> 00:01:52,957
But the reason is that they're warning people

45
00:01:52,957 --> 00:01:56,157
about planned future changes to the library.

46
00:01:56,230 --> 00:01:58,430
Anyway, the bottom line is that

47
00:01:58,430 --> 00:02:01,576
we should disable these two options:

48
00:02:01,576 --> 00:02:03,760
"mangle" and "headerIds".

49
00:02:03,848 --> 00:02:05,431
So, let's go and do that.

50
00:02:06,228 --> 00:02:09,059
We can pass an object as second argument,

51
00:02:09,059 --> 00:02:13,271
and here set "headerIds" and "mangle" to "false".

52
00:02:13,271 --> 00:02:15,583
This way we should no longer see

53
00:02:15,583 --> 00:02:17,535
those warnings in the logs.

54
00:02:17,607 --> 00:02:20,120
I suppose in a future version those

55
00:02:20,120 --> 00:02:21,843
options will be removed.

56
00:02:21,915 --> 00:02:24,765
In fact, by the time you watch this video,

57
00:02:24,765 --> 00:02:27,852
maybe this step won't be necessary any more.

58
00:02:27,852 --> 00:02:30,513
Anyway, we still need to get React

59
00:02:30,513 --> 00:02:32,940
to render this "html" variable,

60
00:02:33,018 --> 00:02:35,843
without escaping all the angle brackets.

61
00:02:35,843 --> 00:02:38,716
Let's use an "article" element instead,

62
00:02:38,716 --> 00:02:41,067
since the Markdown content can

63
00:02:41,067 --> 00:02:43,261
contain multiple paragraphs.

64
00:02:43,339 --> 00:02:46,818
Now, to render a value directly as HTML,

65
00:02:46,818 --> 00:02:48,558
without escaping it,

66
00:02:48,645 --> 00:02:53,741
in React we need to use the "dangerouslySetInnerHTML"

67
00:02:53,741 --> 00:02:54,222
prop.

68
00:02:54,318 --> 00:02:57,191
And this must be an object with

69
00:02:57,191 --> 00:02:59,693
a property called "__html",

70
00:02:59,785 --> 00:03:03,012
where we can finally pass the "html" value.

71
00:03:03,012 --> 00:03:06,106
React makes this deliberately complicated,

72
00:03:06,106 --> 00:03:09,025
because they want you to think carefully

73
00:03:09,025 --> 00:03:11,361
before displaying HTML directly.

74
00:03:11,434 --> 00:03:13,557
It can be dangerous to do that,

75
00:03:13,557 --> 00:03:15,611
from a security point of view.

76
00:03:15,679 --> 00:03:18,719
If you directly display some HTML code

77
00:03:18,719 --> 00:03:21,198
that was entered by your users,

78
00:03:21,278 --> 00:03:23,880
that could be exploited for example

79
00:03:23,880 --> 00:03:25,962
by inserting "script" tags

80
00:03:26,036 --> 00:03:28,907
that can then run arbitrary JavaScript

81
00:03:28,907 --> 00:03:30,493
code on your website.

82
00:03:30,569 --> 00:03:32,891
That's why in general it's better

83
00:03:32,891 --> 00:03:34,299
to avoid doing this.

84
00:03:34,369 --> 00:03:36,747
But in our case we know that

85
00:03:36,747 --> 00:03:38,701
the "html" was rendered

86
00:03:38,785 --> 00:03:42,357
from a Markdown file that we wrote ourselves,

87
00:03:42,357 --> 00:03:43,706
not by our users.

88
00:03:43,785 --> 00:03:46,038
So there isn't any risk that it

89
00:03:46,038 --> 00:03:48,073
will contain malicious code.

90
00:03:48,146 --> 00:03:50,994
Anyway, let's finally save this change,

91
00:03:50,994 --> 00:03:53,272
and you can see that the "html"

92
00:03:53,272 --> 00:03:55,109
is now rendered properly,

93
00:03:55,183 --> 00:03:57,436
without displaying all the tags.

94
00:03:57,436 --> 00:04:00,736
Now, it's still not fully styled though.

95
00:04:00,736 --> 00:04:03,500
The "bold" and "italic" text is fine,

96
00:04:03,500 --> 00:04:05,595
but the headings and the list

97
00:04:05,595 --> 00:04:07,473
don't have any formatting.

98
00:04:07,545 --> 00:04:11,318
That's because of the way Tailwind CSS works:

99
00:04:11,318 --> 00:04:13,680
as we've seen, by default it

100
00:04:13,680 --> 00:04:15,958
resets most browser styles.

101
00:04:16,041 --> 00:04:17,951
We'll see in the next video

102
00:04:17,951 --> 00:04:19,718
how to configure Tailwind

103
00:04:19,788 --> 00:04:23,044
to apply some appropriate styles in this case.

104
00:04:23,044 --> 00:04:27,193
But we are now rendering the Markdown to HTML,

105
00:04:27,193 --> 00:04:29,299
using the Marked library.

